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