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,
}
}
for (int i = 0; i < parameters->arity; ++i) {
auto parameter = parameters->at(i);
impl()->DeclareFormalParameter(parameters->scope, parameter);
}
impl()->DeclareFormalParameters(parameters->scope, parameters->params);
}
template <typename Impl>
......
......@@ -964,7 +964,7 @@ FunctionLiteral* Parser::DoParseFunction(ParseInfo* info,
} else {
// BindingIdentifier
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(
if (!parameters->is_simple) {
this->classifier()->RecordNonSimpleParameter();
}
for (int i = 0; i < parameters->arity; ++i) {
auto parameter = parameters->at(i);
DeclareFormalParameter(parameters->scope, parameter);
if (!this->classifier()
->is_valid_formal_parameter_list_without_duplicates() &&
!duplicate_loc->IsValid()) {
*duplicate_loc =
this->classifier()->duplicate_formal_parameter_error().location;
}
DeclareFormalParameters(parameters->scope, parameters->params);
if (!this->classifier()
->is_valid_formal_parameter_list_without_duplicates()) {
*duplicate_loc =
this->classifier()->duplicate_formal_parameter_error().location;
}
DCHECK_EQ(parameters->is_simple, parameters->scope->has_simple_parameters());
}
......@@ -2493,9 +2489,9 @@ void Parser::ReindexLiterals(const ParserFormalParameters& parameters) {
if (function_state_->materialized_literal_count() > 0) {
AstLiteralReindexer reindexer;
for (const auto p : parameters.params) {
if (p.pattern != nullptr) reindexer.Reindex(p.pattern);
if (p.initializer != nullptr) reindexer.Reindex(p.initializer);
for (auto p : parameters.params) {
if (p->pattern != nullptr) reindexer.Reindex(p->pattern);
if (p->initializer != nullptr) reindexer.Reindex(p->initializer);
}
DCHECK(reindexer.count() <= function_state_->materialized_literal_count());
......@@ -2926,44 +2922,44 @@ Block* Parser::BuildParameterInitializationBlock(
DCHECK(!parameters.is_simple);
DCHECK(scope()->is_function_scope());
Block* init_block = factory()->NewBlock(NULL, 1, true, kNoSourcePosition);
for (int i = 0; i < parameters.params.length(); ++i) {
auto parameter = parameters.params[i];
if (parameter.is_rest && parameter.pattern->IsVariableProxy()) break;
int index = 0;
for (auto parameter : parameters.params) {
if (parameter->is_rest && parameter->pattern->IsVariableProxy()) break;
DeclarationDescriptor descriptor;
descriptor.declaration_kind = DeclarationDescriptor::PARAMETER;
descriptor.scope = scope();
descriptor.hoist_scope = nullptr;
descriptor.mode = LET;
descriptor.declaration_pos = parameter.pattern->position();
descriptor.declaration_pos = parameter->pattern->position();
// The position that will be used by the AssignmentExpression
// which copies from the temp parameter to the pattern.
//
// TODO(adamk): Should this be kNoSourcePosition, since
// 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 =
factory()->NewVariableProxy(parameters.scope->parameter(i));
if (parameter.initializer != nullptr) {
factory()->NewVariableProxy(parameters.scope->parameter(index));
if (parameter->initializer != nullptr) {
// IS_UNDEFINED($param) ? initializer : $param
// Ensure initializer is rewritten
RewriteParameterInitializer(parameter.initializer, scope());
RewriteParameterInitializer(parameter->initializer, scope());
auto condition = factory()->NewCompareOperation(
Token::EQ_STRICT,
factory()->NewVariableProxy(parameters.scope->parameter(i)),
factory()->NewVariableProxy(parameters.scope->parameter(index)),
factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition);
initial_value = factory()->NewConditional(
condition, parameter.initializer, initial_value, kNoSourcePosition);
descriptor.initialization_pos = parameter.initializer->position();
condition, parameter->initializer, initial_value, kNoSourcePosition);
descriptor.initialization_pos = parameter->initializer->position();
}
Scope* param_scope = scope();
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->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_block = factory()->NewBlock(NULL, 8, true, kNoSourcePosition);
param_block->set_scope(param_scope);
......@@ -2978,7 +2974,7 @@ Block* Parser::BuildParameterInitializationBlock(
BlockState block_state(&scope_state_, param_scope);
DeclarationParsingResult::Declaration decl(
parameter.pattern, parameter.initializer_end_position, initial_value);
parameter->pattern, parameter->initializer_end_position, initial_value);
PatternRewriter::DeclareAndInitializeVariables(
this, param_block, &descriptor, &decl, nullptr, CHECK_OK);
......@@ -2989,6 +2985,7 @@ Block* Parser::BuildParameterInitializationBlock(
}
init_block->statements()->Add(param_block, zone());
}
++index;
}
return init_block;
}
......
......@@ -14,6 +14,7 @@
#include "src/parsing/preparse-data.h"
#include "src/parsing/preparser.h"
#include "src/pending-compilation-error-handler.h"
#include "src/utils.h"
namespace v8 {
......@@ -135,7 +136,7 @@ class Parser;
struct ParserFormalParameters : FormalParametersBase {
struct Parameter {
struct Parameter : public ZoneObject {
Parameter(const AstRawString* name, Expression* pattern,
Expression* initializer, int initializer_end_position,
bool is_rest)
......@@ -149,16 +150,17 @@ struct ParserFormalParameters : FormalParametersBase {
Expression* initializer;
int initializer_end_position;
bool is_rest;
Parameter* next_parameter = nullptr;
bool is_simple() const {
return pattern->IsVariableProxy() && initializer == nullptr && !is_rest;
}
Parameter** next() { return &next_parameter; }
Parameter* const* next() const { return &next_parameter; }
};
explicit ParserFormalParameters(DeclarationScope* scope)
: FormalParametersBase(scope), params(4, scope->zone()) {}
ZoneList<Parameter> params;
const Parameter& at(int i) const { return params[i]; }
: FormalParametersBase(scope) {}
ThreadedList<Parameter> params;
};
template <>
......@@ -1045,34 +1047,39 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
const AstRawString* name = is_simple
? pattern->AsVariableProxy()->raw_name()
: ast_value_factory()->empty_string();
parameters->params.Add(
ParserFormalParameters::Parameter(name, pattern, initializer,
initializer_end_position, is_rest),
parameters->scope->zone());
auto parameter =
new (parameters->scope->zone()) ParserFormalParameters::Parameter(
name, pattern, initializer, initializer_end_position, is_rest);
parameters->params.Add(parameter);
}
V8_INLINE void DeclareFormalParameter(
V8_INLINE void DeclareFormalParameters(
DeclarationScope* scope,
const ParserFormalParameters::Parameter& parameter) {
bool is_duplicate = false;
bool is_simple = classifier()->is_simple_parameter_list();
auto name = is_simple || parameter.is_rest
? parameter.name
: ast_value_factory()->empty_string();
auto mode = is_simple || parameter.is_rest ? VAR : TEMPORARY;
if (!is_simple) scope->SetHasNonSimpleParameters();
bool is_optional = parameter.initializer != nullptr;
Variable* var =
scope->DeclareParameter(name, mode, is_optional, parameter.is_rest,
&is_duplicate, ast_value_factory());
if (is_duplicate) {
classifier()->RecordDuplicateFormalParameterError(scanner()->location());
}
if (is_sloppy(scope->language_mode())) {
// 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();
const ThreadedList<ParserFormalParameters::Parameter>& parameters) {
for (auto parameter : parameters) {
bool is_duplicate = false;
bool is_simple = classifier()->is_simple_parameter_list();
auto name = is_simple || parameter->is_rest
? parameter->name
: ast_value_factory()->empty_string();
auto mode = is_simple || parameter->is_rest ? VAR : TEMPORARY;
if (!is_simple) scope->SetHasNonSimpleParameters();
bool is_optional = parameter->initializer != nullptr;
Variable* var =
scope->DeclareParameter(name, mode, is_optional, parameter->is_rest,
&is_duplicate, ast_value_factory());
if (is_duplicate &&
classifier()->is_valid_formal_parameter_list_without_duplicates()) {
classifier()->RecordDuplicateFormalParameterError(
scanner()->location());
}
if (is_sloppy(scope->language_mode())) {
// 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 {
struct PreParserFormalParameters : FormalParametersBase {
explicit PreParserFormalParameters(DeclarationScope* scope)
: FormalParametersBase(scope) {}
PreParserIdentifier at(int i) { return PreParserIdentifier(); } // Dummy
void* params = nullptr; // Dummy
};
......@@ -1440,8 +1441,8 @@ class PreParser : public ParserBase<PreParser> {
parameters->UpdateArityAndFunctionLength(!initializer.IsEmpty(), is_rest);
}
V8_INLINE void DeclareFormalParameter(DeclarationScope* scope,
PreParserIdentifier parameter) {
V8_INLINE void DeclareFormalParameters(DeclarationScope* scope,
void* parameters) {
if (!classifier()->is_simple_parameter_list()) {
scope->SetHasNonSimpleParameters();
}
......
......@@ -1627,9 +1627,31 @@ class ThreadedList final {
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 end() { return Iterator(tail_); }
ConstIterator begin() const { return ConstIterator(&head_); }
ConstIterator end() const { return ConstIterator(tail_); }
void Rewind(Iterator reset_point) {
tail_ = reset_point.entry_;
*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