Commit 00566ed4 authored by Florian Sattler's avatar Florian Sattler Committed by Commit Bot

[preparser] Adapted the PreParser to use ThreadedLists

PreParser types, e.g., PreParserExpression, PreParserList,
PreParserFormalParameter.  This also enhances ThreadedLists to be used
on the same class more than once.

Bug: v8:7926
Change-Id: Ied204120e5d12ab1f1c4192f6b3c05971a12683b
Reviewed-on: https://chromium-review.googlesource.com/1199262
Commit-Queue: Florian Sattler <sattlerf@google.com>
Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55584}
parent 4e20a62a
......@@ -397,6 +397,7 @@ class Declaration : public AstNode {
Declaration** next() { return &next_; }
Declaration* next_;
friend List;
friend ThreadedListTraits<Declaration>;
};
class VariableDeclaration : public Declaration {
......@@ -1581,6 +1582,14 @@ class VariableProxy final : public Expression {
void set_next_unresolved(VariableProxy* next) { next_unresolved_ = next; }
VariableProxy* next_unresolved() { return next_unresolved_; }
// Provides an access type for the ThreadedList used by the PreParsers
// expressions, lists, and formal parameters.
struct PreParserNext {
static VariableProxy** next(VariableProxy* t) {
return t->pre_parser_expr_next();
}
};
private:
friend class AstNodeFactory;
......@@ -1590,7 +1599,8 @@ class VariableProxy final : public Expression {
int start_position)
: Expression(start_position, kVariableProxy),
raw_name_(name),
next_unresolved_(nullptr) {
next_unresolved_(nullptr),
pre_parser_expr_next_(nullptr) {
bit_field_ |= IsThisField::encode(variable_kind == THIS_VARIABLE) |
IsAssignedField::encode(false) |
IsResolvedField::encode(false) |
......@@ -1614,8 +1624,10 @@ class VariableProxy final : public Expression {
Variable* var_; // if is_resolved_
};
VariableProxy* next_unresolved_;
};
VariableProxy** pre_parser_expr_next() { return &pre_parser_expr_next_; }
VariableProxy* pre_parser_expr_next_;
};
// Left-hand side can only be a property, a global or a (parameter or local)
// slot.
......
......@@ -215,6 +215,7 @@ class Variable final : public ZoneObject {
ForceHoleInitializationField::kNext, 1> {};
Variable** next() { return &next_; }
friend List;
friend ThreadedListTraits<Variable>;
};
} // namespace internal
} // namespace v8
......
......@@ -86,16 +86,18 @@ class PreParserIdentifier {
friend class PreParserFactory;
};
class PreParserExpression {
public:
using VariableZoneThreadedListType =
ZoneThreadedList<VariableProxy, VariableProxy::PreParserNext>;
PreParserExpression()
: code_(TypeField::encode(kNull)), variables_(nullptr) {}
static PreParserExpression Null() { return PreParserExpression(); }
static PreParserExpression Default(
ZonePtrList<VariableProxy>* variables = nullptr) {
VariableZoneThreadedListType* variables = nullptr) {
return PreParserExpression(TypeField::encode(kExpression), variables);
}
......@@ -124,9 +126,7 @@ class PreParserExpression {
right.variables_);
}
if (right.variables_ != nullptr) {
for (auto variable : *right.variables_) {
left.variables_->Add(variable, zone);
}
left.variables_->Append(right.variables_);
}
return PreParserExpression(TypeField::encode(kExpression),
left.variables_);
......@@ -134,7 +134,8 @@ class PreParserExpression {
return PreParserExpression(TypeField::encode(kExpression));
}
static PreParserExpression Assignment(ZonePtrList<VariableProxy>* variables) {
static PreParserExpression Assignment(
VariableZoneThreadedListType* variables) {
return PreParserExpression(TypeField::encode(kExpression) |
ExpressionTypeField::encode(kAssignment),
variables);
......@@ -145,13 +146,13 @@ class PreParserExpression {
}
static PreParserExpression ObjectLiteral(
ZonePtrList<VariableProxy>* variables) {
VariableZoneThreadedListType* variables) {
return PreParserExpression(TypeField::encode(kObjectLiteralExpression),
variables);
}
static PreParserExpression ArrayLiteral(
ZonePtrList<VariableProxy>* variables) {
VariableZoneThreadedListType* variables) {
return PreParserExpression(TypeField::encode(kArrayLiteralExpression),
variables);
}
......@@ -170,7 +171,7 @@ class PreParserExpression {
IsUseAsmField::encode(true));
}
static PreParserExpression This(ZonePtrList<VariableProxy>* variables) {
static PreParserExpression This(VariableZoneThreadedListType* variables) {
return PreParserExpression(TypeField::encode(kExpression) |
ExpressionTypeField::encode(kThisExpression),
variables);
......@@ -335,7 +336,7 @@ class PreParserExpression {
if (variables_ != nullptr) {
DCHECK(IsIdentifier());
DCHECK(AsIdentifier().IsPrivateName());
DCHECK_EQ(1, variables_->length());
DCHECK_EQ(1, variables_->LengthForTest());
variables_->first()->set_is_private_field();
}
}
......@@ -373,8 +374,9 @@ class PreParserExpression {
kAssignment
};
explicit PreParserExpression(uint32_t expression_code,
ZonePtrList<VariableProxy>* variables = nullptr)
explicit PreParserExpression(
uint32_t expression_code,
VariableZoneThreadedListType* variables = nullptr)
: code_(expression_code), variables_(variables) {}
void AddVariable(VariableProxy* variable, Zone* zone) {
......@@ -382,9 +384,9 @@ class PreParserExpression {
return;
}
if (variables_ == nullptr) {
variables_ = new (zone) ZonePtrList<VariableProxy>(1, zone);
variables_ = new (zone) VariableZoneThreadedListType();
}
variables_->Add(variable, zone);
variables_->Add(variable);
}
// The first three bits are for the Type.
......@@ -409,7 +411,7 @@ class PreParserExpression {
uint32_t code_;
// If the PreParser is used in the variable tracking mode, PreParserExpression
// accumulates variables in that expression.
ZonePtrList<VariableProxy>* variables_;
VariableZoneThreadedListType* variables_;
friend class PreParser;
friend class PreParserFactory;
......@@ -423,6 +425,9 @@ class PreParserExpression {
// build lists of variables though.
template <typename T>
class PreParserList {
using VariableZoneThreadedListType =
ZoneThreadedList<VariableProxy, VariableProxy::PreParserNext>;
public:
// These functions make list->Add(some_expression) work (and do nothing).
PreParserList() : length_(0), variables_(nullptr) {}
......@@ -436,7 +441,8 @@ class PreParserList {
private:
explicit PreParserList(int n) : length_(n), variables_(nullptr) {}
int length_;
ZonePtrList<VariableProxy>* variables_;
VariableZoneThreadedListType* variables_;
friend class PreParser;
friend class PreParserFactory;
......@@ -449,11 +455,9 @@ inline void PreParserList<PreParserExpression>::Add(
DCHECK(FLAG_lazy_inner_functions);
DCHECK_NOT_NULL(zone);
if (variables_ == nullptr) {
variables_ = new (zone) ZonePtrList<VariableProxy>(1, zone);
}
for (auto identifier : (*expression.variables_)) {
variables_->Add(identifier, zone);
variables_ = new (zone) VariableZoneThreadedListType();
}
variables_->Append(expression.variables_);
}
++length_;
}
......@@ -851,12 +855,15 @@ class PreParserFactory {
struct PreParserFormalParameters : FormalParametersBase {
struct Parameter : public ZoneObject {
Parameter(ZonePtrList<VariableProxy>* variables, bool is_rest)
using VariableZoneThreadedListType =
ZoneThreadedList<VariableProxy, VariableProxy::PreParserNext>;
Parameter(VariableZoneThreadedListType* variables, bool is_rest)
: variables_(variables), is_rest(is_rest) {}
Parameter** next() { return &next_parameter; }
Parameter* const* next() const { return &next_parameter; }
ZonePtrList<VariableProxy>* variables_;
VariableZoneThreadedListType* variables_;
Parameter* next_parameter = nullptr;
bool is_rest : 1;
};
......@@ -1561,14 +1568,15 @@ class PreParser : public ParserBase<PreParser> {
}
V8_INLINE PreParserExpression ThisExpression(int pos = kNoSourcePosition) {
ZonePtrList<VariableProxy>* variables = nullptr;
PreParserExpression::VariableZoneThreadedListType* variables = nullptr;
if (track_unresolved_variables_) {
VariableProxy* proxy = scope()->NewUnresolved(
factory()->ast_node_factory(), ast_value_factory()->this_string(),
pos, THIS_VARIABLE);
variables = new (zone()) ZonePtrList<VariableProxy>(1, zone());
variables->Add(proxy, zone());
variables =
new (zone()) PreParserExpression::VariableZoneThreadedListType();
variables->Add(proxy);
}
return PreParserExpression::This(variables);
}
......@@ -1681,7 +1689,7 @@ class PreParser : public ParserBase<PreParser> {
DCHECK(FLAG_lazy_inner_functions);
for (auto parameter : parameters) {
DCHECK_IMPLIES(is_simple, parameter->variables_ != nullptr);
DCHECK_IMPLIES(is_simple, parameter->variables_->length() == 1);
DCHECK_IMPLIES(is_simple, parameter->variables_->LengthForTest() == 1);
// Make sure each parameter is added only once even if it's a
// destructuring parameter which contains multiple names.
bool add_parameter = true;
......
......@@ -1622,18 +1622,30 @@ static inline V ByteReverse(V value) {
}
}
// Represents a linked list that threads through the nodes in the linked list.
// Entries in the list are pointers to nodes. The nodes need to have a T**
// next() method that returns the location where the next value is stored.
template <typename T>
class ThreadedList final {
struct ThreadedListTraits {
static T** next(T* t) { return t->next(); }
};
// Represents a linked list that threads through the nodes in the linked list.
// Entries in the list are pointers to nodes. By default nodes need to have a
// T** next() method that returns the location where the next value is stored.
// The default can be overwritten by providing a ThreadedTraits class.
template <typename T, typename BaseClass,
typename TLTraits = ThreadedListTraits<T>>
class ThreadedListBase final : public BaseClass {
public:
ThreadedList() : head_(nullptr), tail_(&head_) {}
ThreadedListBase() : head_(nullptr), tail_(&head_) {}
void Add(T* v) {
DCHECK_NULL(*tail_);
DCHECK_NULL(*v->next());
DCHECK_NULL(*TLTraits::next(v));
*tail_ = v;
tail_ = v->next();
tail_ = TLTraits::next(v);
}
void Append(ThreadedListBase* list) {
*tail_ = list->head_;
tail_ = list->tail_;
}
void Clear() {
......@@ -1644,15 +1656,15 @@ class ThreadedList final {
class Iterator final {
public:
Iterator& operator++() {
entry_ = (*entry_)->next();
entry_ = TLTraits::next(*entry_);
return *this;
}
bool operator!=(const Iterator& other) { return entry_ != other.entry_; }
T* operator*() { return *entry_; }
T* operator->() { return *entry_; }
Iterator& operator=(T* entry) {
T* next = *(*entry_)->next();
*entry->next() = next;
T* next = *TLTraits::next(*entry_);
*TLTraits::next(entry) = next;
*entry_ = entry;
return *this;
}
......@@ -1662,13 +1674,13 @@ class ThreadedList final {
T** entry_;
friend class ThreadedList;
friend class ThreadedListBase;
};
class ConstIterator final {
public:
ConstIterator& operator++() {
entry_ = (*entry_)->next();
entry_ = TLTraits::next(*entry_);
return *this;
}
bool operator!=(const ConstIterator& other) {
......@@ -1681,7 +1693,7 @@ class ThreadedList final {
T* const* entry_;
friend class ThreadedList;
friend class ThreadedListBase;
};
Iterator begin() { return Iterator(&head_); }
......@@ -1695,7 +1707,7 @@ class ThreadedList final {
*tail_ = nullptr;
}
void MoveTail(ThreadedList<T>* parent, Iterator location) {
void MoveTail(ThreadedListBase<T, BaseClass>* parent, Iterator location) {
if (parent->end() != location) {
DCHECK_NULL(*tail_);
*tail_ = *location;
......@@ -1706,6 +1718,8 @@ class ThreadedList final {
bool is_empty() const { return head_ == nullptr; }
T* first() { return head_; }
// Slow. For testing purposes.
int LengthForTest() {
int result = 0;
......@@ -1721,9 +1735,14 @@ class ThreadedList final {
private:
T* head_;
T** tail_;
DISALLOW_COPY_AND_ASSIGN(ThreadedList);
DISALLOW_COPY_AND_ASSIGN(ThreadedListBase);
};
struct EmptyBase {};
template <typename T, typename TLTraits = ThreadedListTraits<T>>
using ThreadedList = ThreadedListBase<T, EmptyBase, TLTraits>;
V8_EXPORT_PRIVATE bool PassesFilter(Vector<const char> name,
Vector<const char> filter);
......
......@@ -11,6 +11,7 @@
#include "src/base/logging.h"
#include "src/globals.h"
#include "src/splay-tree.h"
#include "src/utils.h"
#include "src/zone/accounting-allocator.h"
#ifndef ZONE_NAME
......@@ -295,6 +296,11 @@ class ZoneList final {
template <typename T>
using ZonePtrList = ZoneList<T*>;
// ZoneThreadedList is a special variant of the ThreadedList that can be put
// into a Zone.
template <typename T, typename TLTraits = ThreadedListTraits<T>>
using ZoneThreadedList = ThreadedListBase<T, ZoneObject, TLTraits>;
// A zone splay tree. The config type parameter encapsulates the
// different configurations of a concrete splay tree (see splay-tree.h).
// The tree itself and all its elements are allocated in the Zone.
......
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