Commit 9e99c92c authored by neis's avatar neis Committed by Commit bot

[ast] Annotate some nodes with number of yields.

Annotate generator functions and loops therein with the number of contained
yields.  This information will eventually be used by the bytecode generator.

R=bmeurer@chromium.org
BUG=v8:4907
LOG=n

Review URL: https://codereview.chromium.org/1877403003

Cr-Commit-Position: refs/heads/master@{#35439}
parent b4df8dab
...@@ -17,6 +17,7 @@ class AstNumberingVisitor final : public AstVisitor { ...@@ -17,6 +17,7 @@ class AstNumberingVisitor final : public AstVisitor {
isolate_(isolate), isolate_(isolate),
zone_(zone), zone_(zone),
next_id_(BailoutId::FirstUsable().ToInt()), next_id_(BailoutId::FirstUsable().ToInt()),
yield_count_(0),
properties_(zone), properties_(zone),
slot_cache_(zone), slot_cache_(zone),
dont_optimize_reason_(kNoReason) { dont_optimize_reason_(kNoReason) {
...@@ -31,8 +32,6 @@ class AstNumberingVisitor final : public AstVisitor { ...@@ -31,8 +32,6 @@ class AstNumberingVisitor final : public AstVisitor {
AST_NODE_LIST(DEFINE_VISIT) AST_NODE_LIST(DEFINE_VISIT)
#undef DEFINE_VISIT #undef DEFINE_VISIT
bool Finish(FunctionLiteral* node);
void VisitVariableProxyReference(VariableProxy* node); void VisitVariableProxyReference(VariableProxy* node);
void VisitPropertyReference(Property* node); void VisitPropertyReference(Property* node);
void VisitReference(Expression* expr); void VisitReference(Expression* expr);
...@@ -73,9 +72,21 @@ class AstNumberingVisitor final : public AstVisitor { ...@@ -73,9 +72,21 @@ class AstNumberingVisitor final : public AstVisitor {
BailoutReason dont_optimize_reason() const { return dont_optimize_reason_; } BailoutReason dont_optimize_reason() const { return dont_optimize_reason_; }
int GetAndResetYieldCount() {
int old_yield_count = yield_count_;
yield_count_ = 0;
return old_yield_count;
}
void StoreAndUpdateYieldCount(IterationStatement* node, int old_yield_count) {
node->set_yield_count(yield_count_);
yield_count_ += old_yield_count;
}
Isolate* isolate_; Isolate* isolate_;
Zone* zone_; Zone* zone_;
int next_id_; int next_id_;
int yield_count_;
AstProperties properties_; AstProperties properties_;
// The slot cache allows us to reuse certain feedback vector slots. // The slot cache allows us to reuse certain feedback vector slots.
FeedbackVectorSlotCache slot_cache_; FeedbackVectorSlotCache slot_cache_;
...@@ -217,6 +228,7 @@ void AstNumberingVisitor::VisitReturnStatement(ReturnStatement* node) { ...@@ -217,6 +228,7 @@ void AstNumberingVisitor::VisitReturnStatement(ReturnStatement* node) {
void AstNumberingVisitor::VisitYield(Yield* node) { void AstNumberingVisitor::VisitYield(Yield* node) {
yield_count_++;
IncrementNodeCount(); IncrementNodeCount();
DisableOptimization(kYield); DisableOptimization(kYield);
ReserveFeedbackSlots(node); ReserveFeedbackSlots(node);
...@@ -284,8 +296,10 @@ void AstNumberingVisitor::VisitDoWhileStatement(DoWhileStatement* node) { ...@@ -284,8 +296,10 @@ void AstNumberingVisitor::VisitDoWhileStatement(DoWhileStatement* node) {
IncrementNodeCount(); IncrementNodeCount();
DisableSelfOptimization(); DisableSelfOptimization();
node->set_base_id(ReserveIdRange(DoWhileStatement::num_ids())); node->set_base_id(ReserveIdRange(DoWhileStatement::num_ids()));
int old_yield_count = GetAndResetYieldCount();
Visit(node->body()); Visit(node->body());
Visit(node->cond()); Visit(node->cond());
StoreAndUpdateYieldCount(node, old_yield_count);
} }
...@@ -293,8 +307,10 @@ void AstNumberingVisitor::VisitWhileStatement(WhileStatement* node) { ...@@ -293,8 +307,10 @@ void AstNumberingVisitor::VisitWhileStatement(WhileStatement* node) {
IncrementNodeCount(); IncrementNodeCount();
DisableSelfOptimization(); DisableSelfOptimization();
node->set_base_id(ReserveIdRange(WhileStatement::num_ids())); node->set_base_id(ReserveIdRange(WhileStatement::num_ids()));
int old_yield_count = GetAndResetYieldCount();
Visit(node->cond()); Visit(node->cond());
Visit(node->body()); Visit(node->body());
StoreAndUpdateYieldCount(node, old_yield_count);
} }
...@@ -377,9 +393,11 @@ void AstNumberingVisitor::VisitForInStatement(ForInStatement* node) { ...@@ -377,9 +393,11 @@ void AstNumberingVisitor::VisitForInStatement(ForInStatement* node) {
IncrementNodeCount(); IncrementNodeCount();
DisableSelfOptimization(); DisableSelfOptimization();
node->set_base_id(ReserveIdRange(ForInStatement::num_ids())); node->set_base_id(ReserveIdRange(ForInStatement::num_ids()));
Visit(node->enumerable()); // Not part of loop.
int old_yield_count = GetAndResetYieldCount();
Visit(node->each()); Visit(node->each());
Visit(node->enumerable());
Visit(node->body()); Visit(node->body());
StoreAndUpdateYieldCount(node, old_yield_count);
ReserveFeedbackSlots(node); ReserveFeedbackSlots(node);
} }
...@@ -388,11 +406,13 @@ void AstNumberingVisitor::VisitForOfStatement(ForOfStatement* node) { ...@@ -388,11 +406,13 @@ void AstNumberingVisitor::VisitForOfStatement(ForOfStatement* node) {
IncrementNodeCount(); IncrementNodeCount();
DisableCrankshaft(kForOfStatement); DisableCrankshaft(kForOfStatement);
node->set_base_id(ReserveIdRange(ForOfStatement::num_ids())); node->set_base_id(ReserveIdRange(ForOfStatement::num_ids()));
Visit(node->assign_iterator()); Visit(node->assign_iterator()); // Not part of loop.
int old_yield_count = GetAndResetYieldCount();
Visit(node->next_result()); Visit(node->next_result());
Visit(node->result_done()); Visit(node->result_done());
Visit(node->assign_each()); Visit(node->assign_each());
Visit(node->body()); Visit(node->body());
StoreAndUpdateYieldCount(node, old_yield_count);
ReserveFeedbackSlots(node); ReserveFeedbackSlots(node);
} }
...@@ -440,10 +460,12 @@ void AstNumberingVisitor::VisitForStatement(ForStatement* node) { ...@@ -440,10 +460,12 @@ void AstNumberingVisitor::VisitForStatement(ForStatement* node) {
IncrementNodeCount(); IncrementNodeCount();
DisableSelfOptimization(); DisableSelfOptimization();
node->set_base_id(ReserveIdRange(ForStatement::num_ids())); node->set_base_id(ReserveIdRange(ForStatement::num_ids()));
if (node->init() != NULL) Visit(node->init()); if (node->init() != NULL) Visit(node->init()); // Not part of loop.
int old_yield_count = GetAndResetYieldCount();
if (node->cond() != NULL) Visit(node->cond()); if (node->cond() != NULL) Visit(node->cond());
if (node->next() != NULL) Visit(node->next()); if (node->next() != NULL) Visit(node->next());
Visit(node->body()); Visit(node->body());
StoreAndUpdateYieldCount(node, old_yield_count);
} }
...@@ -554,13 +576,6 @@ void AstNumberingVisitor::VisitRewritableExpression( ...@@ -554,13 +576,6 @@ void AstNumberingVisitor::VisitRewritableExpression(
} }
bool AstNumberingVisitor::Finish(FunctionLiteral* node) {
node->set_ast_properties(&properties_);
node->set_dont_optimize_reason(dont_optimize_reason());
return !HasStackOverflow();
}
bool AstNumberingVisitor::Renumber(FunctionLiteral* node) { bool AstNumberingVisitor::Renumber(FunctionLiteral* node) {
Scope* scope = node->scope(); Scope* scope = node->scope();
if (scope->new_target_var()) DisableCrankshaft(kSuperReference); if (scope->new_target_var()) DisableCrankshaft(kSuperReference);
...@@ -577,7 +592,10 @@ bool AstNumberingVisitor::Renumber(FunctionLiteral* node) { ...@@ -577,7 +592,10 @@ bool AstNumberingVisitor::Renumber(FunctionLiteral* node) {
VisitDeclarations(scope->declarations()); VisitDeclarations(scope->declarations());
VisitStatements(node->body()); VisitStatements(node->body());
return Finish(node); node->set_ast_properties(&properties_);
node->set_dont_optimize_reason(dont_optimize_reason());
node->set_yield_count(yield_count_);
return !HasStackOverflow();
} }
......
...@@ -14,8 +14,9 @@ class Isolate; ...@@ -14,8 +14,9 @@ class Isolate;
class Zone; class Zone;
namespace AstNumbering { namespace AstNumbering {
// Assign type feedback IDs and bailout IDs to an AST node tree. // Assign type feedback IDs and bailout IDs to an AST node tree. For a
// // generator function, also annotate the function itself and any loops therein
// with the number of contained yields.
bool Renumber(Isolate* isolate, Zone* zone, FunctionLiteral* function); bool Renumber(Isolate* isolate, Zone* zone, FunctionLiteral* function);
} }
......
...@@ -647,6 +647,9 @@ class IterationStatement : public BreakableStatement { ...@@ -647,6 +647,9 @@ class IterationStatement : public BreakableStatement {
Statement* body() const { return body_; } Statement* body() const { return body_; }
void set_body(Statement* s) { body_ = s; } void set_body(Statement* s) { body_ = s; }
int yield_count() { return yield_count_; }
void set_yield_count(int yield_count) { yield_count_ = yield_count; }
static int num_ids() { return parent_num_ids() + 1; } static int num_ids() { return parent_num_ids() + 1; }
BailoutId OsrEntryId() const { return BailoutId(local_id(0)); } BailoutId OsrEntryId() const { return BailoutId(local_id(0)); }
virtual BailoutId ContinueId() const = 0; virtual BailoutId ContinueId() const = 0;
...@@ -658,7 +661,8 @@ class IterationStatement : public BreakableStatement { ...@@ -658,7 +661,8 @@ class IterationStatement : public BreakableStatement {
protected: protected:
IterationStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos) IterationStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
: BreakableStatement(zone, labels, TARGET_FOR_ANONYMOUS, pos), : BreakableStatement(zone, labels, TARGET_FOR_ANONYMOUS, pos),
body_(NULL) {} body_(NULL),
yield_count_(0) {}
static int parent_num_ids() { return BreakableStatement::num_ids(); } static int parent_num_ids() { return BreakableStatement::num_ids(); }
void Initialize(Statement* body) { body_ = body; } void Initialize(Statement* body) { body_ = body; }
...@@ -667,6 +671,7 @@ class IterationStatement : public BreakableStatement { ...@@ -667,6 +671,7 @@ class IterationStatement : public BreakableStatement {
Statement* body_; Statement* body_;
Label continue_target_; Label continue_target_;
int yield_count_;
}; };
...@@ -2686,6 +2691,9 @@ class FunctionLiteral final : public Expression { ...@@ -2686,6 +2691,9 @@ class FunctionLiteral final : public Expression {
return is_anonymous_expression(); return is_anonymous_expression();
} }
int yield_count() { return yield_count_; }
void set_yield_count(int yield_count) { yield_count_ = yield_count; }
protected: protected:
FunctionLiteral(Zone* zone, const AstString* name, FunctionLiteral(Zone* zone, const AstString* name,
AstValueFactory* ast_value_factory, Scope* scope, AstValueFactory* ast_value_factory, Scope* scope,
...@@ -2705,7 +2713,8 @@ class FunctionLiteral final : public Expression { ...@@ -2705,7 +2713,8 @@ class FunctionLiteral final : public Expression {
materialized_literal_count_(materialized_literal_count), materialized_literal_count_(materialized_literal_count),
expected_property_count_(expected_property_count), expected_property_count_(expected_property_count),
parameter_count_(parameter_count), parameter_count_(parameter_count),
function_token_position_(RelocInfo::kNoPosition) { function_token_position_(RelocInfo::kNoPosition),
yield_count_(0) {
bitfield_ = bitfield_ =
IsDeclaration::encode(function_type == kDeclaration) | IsDeclaration::encode(function_type == kDeclaration) |
IsNamedExpression::encode(function_type == kNamedExpression) | IsNamedExpression::encode(function_type == kNamedExpression) |
...@@ -2746,6 +2755,7 @@ class FunctionLiteral final : public Expression { ...@@ -2746,6 +2755,7 @@ class FunctionLiteral final : public Expression {
int expected_property_count_; int expected_property_count_;
int parameter_count_; int parameter_count_;
int function_token_position_; int function_token_position_;
int yield_count_;
}; };
......
...@@ -1192,6 +1192,10 @@ void AstPrinter::PrintIndentedVisit(const char* s, AstNode* node) { ...@@ -1192,6 +1192,10 @@ void AstPrinter::PrintIndentedVisit(const char* s, AstNode* node) {
const char* AstPrinter::PrintProgram(FunctionLiteral* program) { const char* AstPrinter::PrintProgram(FunctionLiteral* program) {
Init(); Init();
{ IndentedScope indent(this, "FUNC", program->position()); { IndentedScope indent(this, "FUNC", program->position());
PrintIndented("KIND");
Print(" %d\n", program->kind());
PrintIndented("YIELD COUNT");
Print(" %d\n", program->yield_count());
PrintLiteralIndented("NAME", program->name(), true); PrintLiteralIndented("NAME", program->name(), true);
PrintLiteralIndented("INFERRED NAME", program->inferred_name(), true); PrintLiteralIndented("INFERRED NAME", program->inferred_name(), true);
PrintParameters(program->scope()); PrintParameters(program->scope());
...@@ -1360,6 +1364,8 @@ void AstPrinter::VisitCaseClause(CaseClause* clause) { ...@@ -1360,6 +1364,8 @@ void AstPrinter::VisitCaseClause(CaseClause* clause) {
void AstPrinter::VisitDoWhileStatement(DoWhileStatement* node) { void AstPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
IndentedScope indent(this, "DO", node->position()); IndentedScope indent(this, "DO", node->position());
PrintIndented("YIELD COUNT");
Print(" %d\n", node->yield_count());
PrintLabelsIndented(node->labels()); PrintLabelsIndented(node->labels());
PrintIndentedVisit("BODY", node->body()); PrintIndentedVisit("BODY", node->body());
PrintIndentedVisit("COND", node->cond()); PrintIndentedVisit("COND", node->cond());
...@@ -1368,6 +1374,8 @@ void AstPrinter::VisitDoWhileStatement(DoWhileStatement* node) { ...@@ -1368,6 +1374,8 @@ void AstPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
void AstPrinter::VisitWhileStatement(WhileStatement* node) { void AstPrinter::VisitWhileStatement(WhileStatement* node) {
IndentedScope indent(this, "WHILE", node->position()); IndentedScope indent(this, "WHILE", node->position());
PrintIndented("YIELD COUNT");
Print(" %d\n", node->yield_count());
PrintLabelsIndented(node->labels()); PrintLabelsIndented(node->labels());
PrintIndentedVisit("COND", node->cond()); PrintIndentedVisit("COND", node->cond());
PrintIndentedVisit("BODY", node->body()); PrintIndentedVisit("BODY", node->body());
...@@ -1376,6 +1384,8 @@ void AstPrinter::VisitWhileStatement(WhileStatement* node) { ...@@ -1376,6 +1384,8 @@ void AstPrinter::VisitWhileStatement(WhileStatement* node) {
void AstPrinter::VisitForStatement(ForStatement* node) { void AstPrinter::VisitForStatement(ForStatement* node) {
IndentedScope indent(this, "FOR", node->position()); IndentedScope indent(this, "FOR", node->position());
PrintIndented("YIELD COUNT");
Print(" %d\n", node->yield_count());
PrintLabelsIndented(node->labels()); PrintLabelsIndented(node->labels());
if (node->init()) PrintIndentedVisit("INIT", node->init()); if (node->init()) PrintIndentedVisit("INIT", node->init());
if (node->cond()) PrintIndentedVisit("COND", node->cond()); if (node->cond()) PrintIndentedVisit("COND", node->cond());
...@@ -1386,6 +1396,8 @@ void AstPrinter::VisitForStatement(ForStatement* node) { ...@@ -1386,6 +1396,8 @@ void AstPrinter::VisitForStatement(ForStatement* node) {
void AstPrinter::VisitForInStatement(ForInStatement* node) { void AstPrinter::VisitForInStatement(ForInStatement* node) {
IndentedScope indent(this, "FOR IN", node->position()); IndentedScope indent(this, "FOR IN", node->position());
PrintIndented("YIELD COUNT");
Print(" %d\n", node->yield_count());
PrintIndentedVisit("FOR", node->each()); PrintIndentedVisit("FOR", node->each());
PrintIndentedVisit("IN", node->enumerable()); PrintIndentedVisit("IN", node->enumerable());
PrintIndentedVisit("BODY", node->body()); PrintIndentedVisit("BODY", node->body());
...@@ -1394,6 +1406,8 @@ void AstPrinter::VisitForInStatement(ForInStatement* node) { ...@@ -1394,6 +1406,8 @@ void AstPrinter::VisitForInStatement(ForInStatement* node) {
void AstPrinter::VisitForOfStatement(ForOfStatement* node) { void AstPrinter::VisitForOfStatement(ForOfStatement* node) {
IndentedScope indent(this, "FOR OF", node->position()); IndentedScope indent(this, "FOR OF", node->position());
PrintIndented("YIELD COUNT");
Print(" %d\n", node->yield_count());
PrintIndentedVisit("FOR", node->each()); PrintIndentedVisit("FOR", node->each());
PrintIndentedVisit("OF", node->iterable()); PrintIndentedVisit("OF", node->iterable());
PrintIndentedVisit("BODY", node->body()); PrintIndentedVisit("BODY", node->body());
......
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