Commit b5843923 authored by Adam Klein's avatar Adam Klein Committed by Commit Bot

[generators] Remove generator_object_ member from Suspend AST node

Now that the BytecodeGenerator has a dedicated register holding
the generator object, BytecodeGenerator::VisitSuspend can
access the generator directly from that register. This reduces
by one the number of live registers at each suspend point.

Bug: v8:6351, v8:6460
Change-Id: I380a9d2bd8ca7eec6720e5392c1ca07dd0df0e2d
Reviewed-on: https://chromium-review.googlesource.com/522982
Commit-Queue: Adam Klein <adamk@chromium.org>
Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#45710}
parent 218b4d30
...@@ -267,7 +267,6 @@ void AstExpressionRewriter::VisitAssignment(Assignment* node) { ...@@ -267,7 +267,6 @@ void AstExpressionRewriter::VisitAssignment(Assignment* node) {
void AstExpressionRewriter::VisitSuspend(Suspend* node) { void AstExpressionRewriter::VisitSuspend(Suspend* node) {
REWRITE_THIS(node); REWRITE_THIS(node);
AST_REWRITE_PROPERTY(Expression, node, generator_object);
AST_REWRITE_PROPERTY(Expression, node, expression); AST_REWRITE_PROPERTY(Expression, node, expression);
} }
......
...@@ -246,7 +246,6 @@ void AstNumberingVisitor::VisitSuspend(Suspend* node) { ...@@ -246,7 +246,6 @@ void AstNumberingVisitor::VisitSuspend(Suspend* node) {
suspend_count_++; suspend_count_++;
IncrementNodeCount(); IncrementNodeCount();
node->set_base_id(ReserveIdRange(Suspend::num_ids())); node->set_base_id(ReserveIdRange(Suspend::num_ids()));
Visit(node->generator_object());
Visit(node->expression()); Visit(node->expression());
} }
......
...@@ -359,7 +359,6 @@ void AstTraversalVisitor<Subclass>::VisitAssignment(Assignment* expr) { ...@@ -359,7 +359,6 @@ void AstTraversalVisitor<Subclass>::VisitAssignment(Assignment* expr) {
template <class Subclass> template <class Subclass>
void AstTraversalVisitor<Subclass>::VisitSuspend(Suspend* expr) { void AstTraversalVisitor<Subclass>::VisitSuspend(Suspend* expr) {
PROCESS_EXPRESSION(expr); PROCESS_EXPRESSION(expr);
RECURSE_EXPRESSION(Visit(expr->generator_object()));
RECURSE_EXPRESSION(Visit(expr->expression())); RECURSE_EXPRESSION(Visit(expr->expression()));
} }
......
...@@ -2512,7 +2512,6 @@ class Suspend final : public Expression { ...@@ -2512,7 +2512,6 @@ class Suspend final : public Expression {
// desugar yield*. // desugar yield*.
enum OnAbruptResume { kOnExceptionThrow, kOnExceptionRethrow, kNoControl }; enum OnAbruptResume { kOnExceptionThrow, kOnExceptionRethrow, kNoControl };
Expression* generator_object() const { return generator_object_; }
Expression* expression() const { return expression_; } Expression* expression() const { return expression_; }
OnAbruptResume on_abrupt_resume() const { OnAbruptResume on_abrupt_resume() const {
return OnAbruptResumeField::decode(bit_field_); return OnAbruptResumeField::decode(bit_field_);
...@@ -2543,7 +2542,6 @@ class Suspend final : public Expression { ...@@ -2543,7 +2542,6 @@ class Suspend final : public Expression {
SuspendFlags::kAsyncGenerator; SuspendFlags::kAsyncGenerator;
} }
void set_generator_object(Expression* e) { generator_object_ = e; }
void set_expression(Expression* e) { expression_ = e; } void set_expression(Expression* e) { expression_ = e; }
void set_suspend_id(int id) { suspend_id_ = id; } void set_suspend_id(int id) { suspend_id_ = id; }
void set_suspend_type(SuspendFlags type) { void set_suspend_type(SuspendFlags type) {
...@@ -2554,18 +2552,14 @@ class Suspend final : public Expression { ...@@ -2554,18 +2552,14 @@ class Suspend final : public Expression {
private: private:
friend class AstNodeFactory; friend class AstNodeFactory;
Suspend(Expression* generator_object, Expression* expression, int pos, Suspend(Expression* expression, int pos, OnAbruptResume on_abrupt_resume,
OnAbruptResume on_abrupt_resume, SuspendFlags flags) SuspendFlags flags)
: Expression(pos, kSuspend), : Expression(pos, kSuspend), suspend_id_(-1), expression_(expression) {
suspend_id_(-1),
generator_object_(generator_object),
expression_(expression) {
bit_field_ |= OnAbruptResumeField::encode(on_abrupt_resume) | bit_field_ |= OnAbruptResumeField::encode(on_abrupt_resume) |
FlagsField::encode(flags); FlagsField::encode(flags);
} }
int suspend_id_; int suspend_id_;
Expression* generator_object_;
Expression* expression_; Expression* expression_;
class OnAbruptResumeField class OnAbruptResumeField
...@@ -3555,12 +3549,11 @@ class AstNodeFactory final BASE_EMBEDDED { ...@@ -3555,12 +3549,11 @@ class AstNodeFactory final BASE_EMBEDDED {
return assign; return assign;
} }
Suspend* NewSuspend(Expression* generator_object, Expression* expression, Suspend* NewSuspend(Expression* expression, int pos,
int pos, Suspend::OnAbruptResume on_abrupt_resume, Suspend::OnAbruptResume on_abrupt_resume,
SuspendFlags flags) { SuspendFlags flags) {
if (!expression) expression = NewUndefinedLiteral(pos); if (!expression) expression = NewUndefinedLiteral(pos);
return new (zone_) return new (zone_) Suspend(expression, pos, on_abrupt_resume, flags);
Suspend(generator_object, expression, pos, on_abrupt_resume, flags);
} }
Throw* NewThrow(Expression* exception, int pos) { Throw* NewThrow(Expression* exception, int pos) {
......
...@@ -150,7 +150,6 @@ void ALAA::VisitObjectLiteral(ObjectLiteral* e) { ...@@ -150,7 +150,6 @@ void ALAA::VisitObjectLiteral(ObjectLiteral* e) {
void ALAA::VisitArrayLiteral(ArrayLiteral* e) { VisitExpressions(e->values()); } void ALAA::VisitArrayLiteral(ArrayLiteral* e) { VisitExpressions(e->values()); }
void ALAA::VisitSuspend(Suspend* stmt) { void ALAA::VisitSuspend(Suspend* stmt) {
Visit(stmt->generator_object());
Visit(stmt->expression()); Visit(stmt->expression());
} }
......
...@@ -468,7 +468,6 @@ void AstTyper::VisitAssignment(Assignment* expr) { ...@@ -468,7 +468,6 @@ void AstTyper::VisitAssignment(Assignment* expr) {
} }
void AstTyper::VisitSuspend(Suspend* expr) { void AstTyper::VisitSuspend(Suspend* expr) {
RECURSE(Visit(expr->generator_object()));
RECURSE(Visit(expr->expression())); RECURSE(Visit(expr->expression()));
// We don't know anything about the result type. // We don't know anything about the result type.
......
...@@ -2521,7 +2521,7 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) { ...@@ -2521,7 +2521,7 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) {
} }
} }
void BytecodeGenerator::BuildGeneratorSuspend(Suspend* expr, Register generator, void BytecodeGenerator::BuildGeneratorSuspend(Suspend* expr,
RegisterList registers_to_save) { RegisterList registers_to_save) {
RegisterAllocationScope register_scope(this); RegisterAllocationScope register_scope(this);
...@@ -2531,7 +2531,7 @@ void BytecodeGenerator::BuildGeneratorSuspend(Suspend* expr, Register generator, ...@@ -2531,7 +2531,7 @@ void BytecodeGenerator::BuildGeneratorSuspend(Suspend* expr, Register generator,
// Save context, registers, and state. Then return. // Save context, registers, and state. Then return.
builder() builder()
->LoadLiteral(Smi::FromInt(expr->suspend_id())) ->LoadLiteral(Smi::FromInt(expr->suspend_id()))
.SuspendGenerator(generator, registers_to_save, expr->flags()); .SuspendGenerator(generator_object_, registers_to_save, expr->flags());
if (expr->IsNonInitialAsyncGeneratorYield()) { if (expr->IsNonInitialAsyncGeneratorYield()) {
// AsyncGenerator yields (with the exception of the initial yield) delegate // AsyncGenerator yields (with the exception of the initial yield) delegate
...@@ -2541,7 +2541,7 @@ void BytecodeGenerator::BuildGeneratorSuspend(Suspend* expr, Register generator, ...@@ -2541,7 +2541,7 @@ void BytecodeGenerator::BuildGeneratorSuspend(Suspend* expr, Register generator,
// AsyncGeneratorYield: // AsyncGeneratorYield:
// perform AsyncGeneratorResolve(<generator>, <value>, false). // perform AsyncGeneratorResolve(<generator>, <value>, false).
builder() builder()
->MoveRegister(generator, args[0]) ->MoveRegister(generator_object_, args[0])
.MoveRegister(value, args[1]) .MoveRegister(value, args[1])
.LoadFalse() .LoadFalse()
.StoreAccumulatorInRegister(args[2]) .StoreAccumulatorInRegister(args[2])
...@@ -2553,7 +2553,7 @@ void BytecodeGenerator::BuildGeneratorSuspend(Suspend* expr, Register generator, ...@@ -2553,7 +2553,7 @@ void BytecodeGenerator::BuildGeneratorSuspend(Suspend* expr, Register generator,
} }
void BytecodeGenerator::BuildGeneratorResume( void BytecodeGenerator::BuildGeneratorResume(
Suspend* expr, Register generator, RegisterList registers_to_restore) { Suspend* expr, RegisterList registers_to_restore) {
RegisterAllocationScope register_scope(this); RegisterAllocationScope register_scope(this);
// Clobbers all registers. // Clobbers all registers.
...@@ -2575,13 +2575,13 @@ void BytecodeGenerator::BuildGeneratorResume( ...@@ -2575,13 +2575,13 @@ void BytecodeGenerator::BuildGeneratorResume(
? Runtime::kInlineAsyncGeneratorGetAwaitInputOrDebugPos ? Runtime::kInlineAsyncGeneratorGetAwaitInputOrDebugPos
: Runtime::kInlineGeneratorGetInputOrDebugPos; : Runtime::kInlineGeneratorGetInputOrDebugPos;
DCHECK(generator.is_valid()); builder()->CallRuntime(get_generator_input, generator_object_);
builder()->CallRuntime(get_generator_input, generator);
if (expr->on_abrupt_resume() != Suspend::kNoControl) { if (expr->on_abrupt_resume() != Suspend::kNoControl) {
builder()->StoreAccumulatorInRegister(input); builder()->StoreAccumulatorInRegister(input);
builder()->CallRuntime(Runtime::kInlineGeneratorGetResumeMode, generator); builder()->CallRuntime(Runtime::kInlineGeneratorGetResumeMode,
generator_object_);
// Now dispatch on resume mode. // Now dispatch on resume mode.
STATIC_ASSERT(JSGeneratorObject::kNext + 1 == JSGeneratorObject::kReturn); STATIC_ASSERT(JSGeneratorObject::kNext + 1 == JSGeneratorObject::kReturn);
...@@ -2630,12 +2630,11 @@ void BytecodeGenerator::BuildGeneratorResume( ...@@ -2630,12 +2630,11 @@ void BytecodeGenerator::BuildGeneratorResume(
} }
void BytecodeGenerator::VisitSuspend(Suspend* expr) { void BytecodeGenerator::VisitSuspend(Suspend* expr) {
Register generator = VisitForRegisterValue(expr->generator_object());
RegisterList registers(0, register_allocator()->next_register_index()); RegisterList registers(0, register_allocator()->next_register_index());
BuildGeneratorSuspend(expr, generator, registers); BuildGeneratorSuspend(expr, registers);
builder()->Bind(generator_jump_table_, static_cast<int>(expr->suspend_id())); builder()->Bind(generator_jump_table_, static_cast<int>(expr->suspend_id()));
// Upon resume, we continue here. // Upon resume, we continue here.
BuildGeneratorResume(expr, generator, registers); BuildGeneratorResume(expr, registers);
} }
void BytecodeGenerator::VisitThrow(Throw* expr) { void BytecodeGenerator::VisitThrow(Throw* expr) {
......
...@@ -136,10 +136,8 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> { ...@@ -136,10 +136,8 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
void BuildNewLocalWithContext(Scope* scope); void BuildNewLocalWithContext(Scope* scope);
void BuildGeneratorPrologue(); void BuildGeneratorPrologue();
void BuildGeneratorSuspend(Suspend* expr, Register generator, void BuildGeneratorSuspend(Suspend* expr, RegisterList registers_to_save);
RegisterList registers_to_save); void BuildGeneratorResume(Suspend* expr, RegisterList registers_to_restore);
void BuildGeneratorResume(Suspend* expr, Register generator,
RegisterList registers_to_restore);
void VisitArgumentsObject(Variable* variable); void VisitArgumentsObject(Variable* variable);
void VisitRestArgumentsArray(Variable* rest); void VisitRestArgumentsArray(Variable* rest);
......
...@@ -1399,16 +1399,15 @@ class ParserBase { ...@@ -1399,16 +1399,15 @@ class ParserBase {
} }
inline SuspendExpressionT BuildSuspend( inline SuspendExpressionT BuildSuspend(
ExpressionT generator, ExpressionT expr, int pos, ExpressionT expr, int pos, Suspend::OnAbruptResume on_abrupt_resume,
Suspend::OnAbruptResume on_abrupt_resume, SuspendFlags suspend_type) { SuspendFlags suspend_type) {
DCHECK_EQ(0, DCHECK_EQ(0,
static_cast<int>(suspend_type & ~SuspendFlags::kSuspendTypeMask)); static_cast<int>(suspend_type & ~SuspendFlags::kSuspendTypeMask));
if (V8_UNLIKELY(is_async_generator())) { if (V8_UNLIKELY(is_async_generator())) {
suspend_type = static_cast<SuspendFlags>(suspend_type | suspend_type = static_cast<SuspendFlags>(suspend_type |
SuspendFlags::kAsyncGenerator); SuspendFlags::kAsyncGenerator);
} }
return factory()->NewSuspend(generator, expr, pos, on_abrupt_resume, return factory()->NewSuspend(expr, pos, on_abrupt_resume, suspend_type);
suspend_type);
} }
// Validation per ES6 object literals. // Validation per ES6 object literals.
...@@ -2970,8 +2969,6 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseYieldExpression( ...@@ -2970,8 +2969,6 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseYieldExpression(
classifier()->RecordFormalParameterInitializerError( classifier()->RecordFormalParameterInitializerError(
scanner()->peek_location(), MessageTemplate::kYieldInParameter); scanner()->peek_location(), MessageTemplate::kYieldInParameter);
Expect(Token::YIELD, CHECK_OK); Expect(Token::YIELD, CHECK_OK);
ExpressionT generator_object =
factory()->NewVariableProxy(function_state_->generator_object_variable());
// The following initialization is necessary. // The following initialization is necessary.
ExpressionT expression = impl()->EmptyExpression(); ExpressionT expression = impl()->EmptyExpression();
bool delegating = false; // yield* bool delegating = false; // yield*
...@@ -2999,7 +2996,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseYieldExpression( ...@@ -2999,7 +2996,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseYieldExpression(
} }
if (delegating) { if (delegating) {
return impl()->RewriteYieldStar(generator_object, expression, pos); return impl()->RewriteYieldStar(expression, pos);
} }
if (!is_async_generator()) { if (!is_async_generator()) {
...@@ -3010,9 +3007,8 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseYieldExpression( ...@@ -3010,9 +3007,8 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseYieldExpression(
// Hackily disambiguate o from o.next and o [Symbol.iterator](). // Hackily disambiguate o from o.next and o [Symbol.iterator]().
// TODO(verwaest): Come up with a better solution. // TODO(verwaest): Come up with a better solution.
ExpressionT yield = ExpressionT yield = BuildSuspend(expression, pos, Suspend::kOnExceptionThrow,
BuildSuspend(generator_object, expression, pos, SuspendFlags::kYield);
Suspend::kOnExceptionThrow, SuspendFlags::kYield);
return yield; return yield;
} }
......
...@@ -3177,17 +3177,12 @@ Variable* Parser::AsyncGeneratorAwaitVariable() { ...@@ -3177,17 +3177,12 @@ Variable* Parser::AsyncGeneratorAwaitVariable() {
} }
Expression* Parser::BuildInitialYield(int pos, FunctionKind kind) { Expression* Parser::BuildInitialYield(int pos, FunctionKind kind) {
// We access the generator object twice: once for the {generator}
// member of the Suspend AST node, and once for the result of
// the initial yield.
Expression* yield_result = Expression* yield_result =
factory()->NewVariableProxy(function_state_->generator_object_variable()); factory()->NewVariableProxy(function_state_->generator_object_variable());
Expression* generator_object =
factory()->NewVariableProxy(function_state_->generator_object_variable());
// The position of the yield is important for reporting the exception // The position of the yield is important for reporting the exception
// caused by calling the .throw method on a generator suspended at the // caused by calling the .throw method on a generator suspended at the
// initial yield (i.e. right after generator instantiation). // initial yield (i.e. right after generator instantiation).
return BuildSuspend(generator_object, yield_result, scope()->start_position(), return BuildSuspend(yield_result, scope()->start_position(),
Suspend::kOnExceptionThrow, SuspendFlags::kYield); Suspend::kOnExceptionThrow, SuspendFlags::kYield);
} }
...@@ -3922,8 +3917,8 @@ Expression* Parser::RewriteAwaitExpression(Expression* value, int await_pos) { ...@@ -3922,8 +3917,8 @@ Expression* Parser::RewriteAwaitExpression(Expression* value, int await_pos) {
Expression* do_expr = factory()->NewDoExpression( Expression* do_expr = factory()->NewDoExpression(
do_block, AsyncGeneratorAwaitVariable(), nopos); do_block, AsyncGeneratorAwaitVariable(), nopos);
return BuildSuspend(generator_object, do_expr, await_pos, return BuildSuspend(do_expr, await_pos, Suspend::kOnExceptionRethrow,
Suspend::kOnExceptionRethrow, SuspendFlags::kAwait); SuspendFlags::kAwait);
} }
// The parser emits calls to AsyncFunctionAwaitCaught or but the // The parser emits calls to AsyncFunctionAwaitCaught or but the
...@@ -3942,8 +3937,7 @@ Expression* Parser::RewriteAwaitExpression(Expression* value, int await_pos) { ...@@ -3942,8 +3937,7 @@ Expression* Parser::RewriteAwaitExpression(Expression* value, int await_pos) {
Expression* do_expr = Expression* do_expr =
factory()->NewDoExpression(do_block, PromiseVariable(), nopos); factory()->NewDoExpression(do_block, PromiseVariable(), nopos);
return factory()->NewSuspend(generator_object, do_expr, await_pos, return factory()->NewSuspend(do_expr, await_pos, Suspend::kOnExceptionRethrow,
Suspend::kOnExceptionRethrow,
SuspendFlags::kAwait); SuspendFlags::kAwait);
} }
...@@ -4288,8 +4282,7 @@ void Parser::SetFunctionName(Expression* value, const AstRawString* name) { ...@@ -4288,8 +4282,7 @@ void Parser::SetFunctionName(Expression* value, const AstRawString* name) {
// output = %_Call(iteratorReturn, iterator, input); // output = %_Call(iteratorReturn, iterator, input);
// if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
Expression* Parser::RewriteYieldStar(Expression* generator, Expression* Parser::RewriteYieldStar(Expression* iterable, int pos) {
Expression* iterable, int pos) {
const int nopos = kNoSourcePosition; const int nopos = kNoSourcePosition;
IteratorType type = IteratorType type =
is_async_generator() ? IteratorType::kAsync : IteratorType::kNormal; is_async_generator() ? IteratorType::kAsync : IteratorType::kNormal;
...@@ -4484,9 +4477,8 @@ Expression* Parser::RewriteYieldStar(Expression* generator, ...@@ -4484,9 +4477,8 @@ Expression* Parser::RewriteYieldStar(Expression* generator,
Statement* yield_output; Statement* yield_output;
{ {
Expression* output_proxy = factory()->NewVariableProxy(var_output); Expression* output_proxy = factory()->NewVariableProxy(var_output);
Suspend* yield = Suspend* yield = BuildSuspend(output_proxy, nopos, Suspend::kNoControl,
BuildSuspend(generator, output_proxy, nopos, Suspend::kNoControl, SuspendFlags::kYieldStar);
SuspendFlags::kYieldStar);
yield_output = factory()->NewExpressionStatement(yield, nopos); yield_output = factory()->NewExpressionStatement(yield, nopos);
} }
......
...@@ -688,8 +688,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) { ...@@ -688,8 +688,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
Block* block, Block* block,
Expression* return_value, bool* ok); Expression* return_value, bool* ok);
Expression* RewriteYieldStar(Expression* generator, Expression* expression, Expression* RewriteYieldStar(Expression* expression, int pos);
int pos);
void AddArrowFunctionFormalParameters(ParserFormalParameters* parameters, void AddArrowFunctionFormalParameters(ParserFormalParameters* parameters,
Expression* params, int end_pos, Expression* params, int end_pos,
......
...@@ -642,8 +642,7 @@ class PreParserFactory { ...@@ -642,8 +642,7 @@ class PreParserFactory {
// default value inside an arrow function parameter list. // default value inside an arrow function parameter list.
return PreParserExpression::Assignment(left.variables_); return PreParserExpression::Assignment(left.variables_);
} }
PreParserExpression NewSuspend(PreParserExpression generator_object, PreParserExpression NewSuspend(PreParserExpression expression, int pos,
PreParserExpression expression, int pos,
Suspend::OnAbruptResume on_abrupt_resume, Suspend::OnAbruptResume on_abrupt_resume,
SuspendFlags flags) { SuspendFlags flags) {
return PreParserExpression::Default(); return PreParserExpression::Default();
...@@ -1014,8 +1013,7 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1014,8 +1013,7 @@ class PreParser : public ParserBase<PreParser> {
PreParserStatement block, PreParserStatement block,
PreParserExpression return_value, PreParserExpression return_value,
bool* ok) {} bool* ok) {}
V8_INLINE PreParserExpression RewriteYieldStar(PreParserExpression generator, V8_INLINE PreParserExpression RewriteYieldStar(PreParserExpression expression,
PreParserExpression expression,
int pos) { int pos) {
return PreParserExpression::Default(); return PreParserExpression::Default();
} }
......
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