Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(133)

Unified Diff: src/interpreter/bytecode-generator.cc

Issue 2894293003: Save/restore only live registers in the generator suspend/resume. (Closed)
Patch Set: Tweak Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/interpreter/bytecode-generator.h ('k') | src/interpreter/bytecode-operands.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/interpreter/bytecode-generator.cc
diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc
index b754897e759335c90ea8c4a94555f3d22d3e6a9f..f2a5d74029bc8f33726b604f218f48c0da6530be 100644
--- a/src/interpreter/bytecode-generator.cc
+++ b/src/interpreter/bytecode-generator.cc
@@ -776,6 +776,7 @@ BytecodeGenerator::BytecodeGenerator(CompilationInfo* info)
execution_context_(nullptr),
execution_result_(nullptr),
generator_jump_table_(nullptr),
+ generator_object_(),
generator_state_(),
loop_depth_(0) {
DCHECK_EQ(closure_scope(), closure_scope()->GetClosureScope());
@@ -962,6 +963,7 @@ void BytecodeGenerator::VisitIterationHeader(IterationStatement* stmt,
void BytecodeGenerator::BuildGeneratorPrologue() {
DCHECK_GT(info()->literal()->suspend_count(), 0);
+ generator_object_ = register_allocator()->NewRegister();
generator_state_ = register_allocator()->NewRegister();
generator_jump_table_ =
builder()->AllocateJumpTable(info()->literal()->suspend_count(), 0);
@@ -970,19 +972,20 @@ void BytecodeGenerator::BuildGeneratorPrologue() {
// indicate that this is a resume call and to pass in the generator object.
// In ordinary calls, new.target is always undefined because generator
// functions are non-constructable.
- Register generator_object = Register::new_target();
+ builder()->MoveRegister(Register::new_target(), generator_object_);
+
BytecodeLabel regular_call;
builder()
- ->LoadAccumulatorWithRegister(generator_object)
+ ->LoadAccumulatorWithRegister(generator_object_)
.JumpIfUndefined(&regular_call);
// This is a resume call. Restore the current context and the registers,
// then perform state dispatch.
Register generator_context = register_allocator()->NewRegister();
builder()
- ->CallRuntime(Runtime::kInlineGeneratorGetContext, generator_object)
+ ->CallRuntime(Runtime::kInlineGeneratorGetContext, generator_object_)
.PushContext(generator_context)
- .ResumeGenerator(generator_object)
+ .RestoreGeneratorState(generator_object_)
.StoreAccumulatorInRegister(generator_state_)
.SwitchOnSmiNoFeedback(generator_jump_table_);
// We fall through when the generator state is not in the jump table.
@@ -2518,8 +2521,8 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) {
}
}
-void BytecodeGenerator::BuildGeneratorSuspend(Suspend* expr,
- Register generator) {
+void BytecodeGenerator::BuildGeneratorSuspend(Suspend* expr, Register generator,
+ RegisterList registers_to_save) {
RegisterAllocationScope register_scope(this);
builder()->SetExpressionPosition(expr);
@@ -2528,7 +2531,7 @@ void BytecodeGenerator::BuildGeneratorSuspend(Suspend* expr,
// Save context, registers, and state. Then return.
builder()
->LoadLiteral(Smi::FromInt(expr->suspend_id()))
- .SuspendGenerator(generator, expr->flags());
+ .SuspendGenerator(generator, registers_to_save, expr->flags());
if (expr->IsNonInitialAsyncGeneratorYield()) {
// AsyncGenerator yields (with the exception of the initial yield) delegate
@@ -2549,10 +2552,13 @@ void BytecodeGenerator::BuildGeneratorSuspend(Suspend* expr,
builder()->Return(); // Hard return (ignore any finally blocks).
}
-void BytecodeGenerator::BuildGeneratorResume(Suspend* expr,
- Register generator) {
+void BytecodeGenerator::BuildGeneratorResume(
+ Suspend* expr, Register generator, RegisterList registers_to_restore) {
RegisterAllocationScope register_scope(this);
+ // Clobbers all registers.
+ builder()->RestoreGeneratorRegisters(generator_object_, registers_to_restore);
+
// Update state to indicate that we have finished resuming. Loop headers
// rely on this.
builder()
@@ -2623,10 +2629,11 @@ void BytecodeGenerator::BuildGeneratorResume(Suspend* expr,
void BytecodeGenerator::VisitSuspend(Suspend* expr) {
Register generator = VisitForRegisterValue(expr->generator_object());
- BuildGeneratorSuspend(expr, generator);
+ RegisterList registers(0, register_allocator()->next_register_index());
+ BuildGeneratorSuspend(expr, generator, registers);
builder()->Bind(generator_jump_table_, static_cast<int>(expr->suspend_id()));
// Upon resume, we continue here.
- BuildGeneratorResume(expr, generator);
+ BuildGeneratorResume(expr, generator, registers);
}
void BytecodeGenerator::VisitThrow(Throw* expr) {
@@ -3728,7 +3735,8 @@ void BytecodeGenerator::BuildGeneratorObjectVariableInitialization() {
builder()
->MoveRegister(Register::function_closure(), args[0])
.MoveRegister(builder()->Receiver(), args[1])
- .CallRuntime(Runtime::kInlineCreateJSGeneratorObject, args);
+ .CallRuntime(Runtime::kInlineCreateJSGeneratorObject, args)
+ .StoreAccumulatorInRegister(generator_object_);
BuildVariableAssignment(closure_scope()->generator_object_var(), Token::INIT,
FeedbackSlot::Invalid(), HoleCheckMode::kElided);
}
« no previous file with comments | « src/interpreter/bytecode-generator.h ('k') | src/interpreter/bytecode-operands.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698