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