Commit 0681deb9 authored by mstarzinger's avatar mstarzinger Committed by Commit bot

[interpreter] Fix destroyed new.target register use.

This fixes a corner-case where the bytecode was using the <new.target>
register directly without going through the local variable. The value
might be clobbered because the deoptimizer doesn't properly restore the
value. The label will causes bytecode pipeline to be flushed and hence
ensure {BytecodeRegisterOptimizer} doesn't reuse <new.target> anymore.

R=rmcilroy@chromium.org
TEST=mjsunit/regress/regress-crbug-645103
BUG=chromium:645103

Review-Url: https://codereview.chromium.org/2325133002
Cr-Commit-Position: refs/heads/master@{#39306}
parent 6c2a217e
...@@ -3280,6 +3280,13 @@ void BytecodeGenerator::VisitNewTargetVariable(Variable* variable) { ...@@ -3280,6 +3280,13 @@ void BytecodeGenerator::VisitNewTargetVariable(Variable* variable) {
// Store the new target we were called with in the given variable. // Store the new target we were called with in the given variable.
builder()->LoadAccumulatorWithRegister(Register::new_target()); builder()->LoadAccumulatorWithRegister(Register::new_target());
VisitVariableAssignment(variable, Token::INIT, FeedbackVectorSlot::Invalid()); VisitVariableAssignment(variable, Token::INIT, FeedbackVectorSlot::Invalid());
// TODO(mstarzinger): The <new.target> register is not set by the deoptimizer
// and we need to make sure {BytecodeRegisterOptimizer} flushes its state
// before a local variable containing the <new.target> is used. Using a label
// as below flushes the entire pipeline, we should be more specific here.
BytecodeLabel flush_state_label;
builder()->Bind(&flush_state_label);
} }
void BytecodeGenerator::VisitFunctionClosureForContext() { void BytecodeGenerator::VisitFunctionClosureForContext() {
......
...@@ -105,16 +105,17 @@ snippet: " ...@@ -105,16 +105,17 @@ snippet: "
" "
frame size: 4 frame size: 4
parameter count: 1 parameter count: 1
bytecode array length: 80 bytecode array length: 82
bytecodes: [ bytecodes: [
B(Mov), R(closure), R(1), B(Mov), R(closure), R(1),
B(Mov), R(new_target), R(0), B(Mov), R(new_target), R(0),
B(Ldar), R(new_target),
/* 113 E> */ B(StackCheck), /* 113 E> */ B(StackCheck),
/* 118 S> */ B(CallRuntime), U16(Runtime::k_GetSuperConstructor), R(closure), U8(1), /* 118 S> */ B(CallRuntime), U16(Runtime::k_GetSuperConstructor), R(1), U8(1),
B(Star), R(2), B(Star), R(2),
B(LdaSmi), U8(1), B(LdaSmi), U8(1),
B(Star), R(3), B(Star), R(3),
B(Ldar), R(new_target), B(Ldar), R(0),
/* 118 E> */ B(New), R(2), R(3), U8(1), U8(0), /* 118 E> */ B(New), R(2), R(3), U8(1), U8(0),
B(Star), R(2), B(Star), R(2),
B(Ldar), R(this), B(Ldar), R(this),
...@@ -161,14 +162,15 @@ snippet: " ...@@ -161,14 +162,15 @@ snippet: "
" "
frame size: 4 frame size: 4
parameter count: 1 parameter count: 1
bytecode array length: 76 bytecode array length: 78
bytecodes: [ bytecodes: [
B(Mov), R(closure), R(1), B(Mov), R(closure), R(1),
B(Mov), R(new_target), R(0), B(Mov), R(new_target), R(0),
B(Ldar), R(new_target),
/* 112 E> */ B(StackCheck), /* 112 E> */ B(StackCheck),
/* 117 S> */ B(CallRuntime), U16(Runtime::k_GetSuperConstructor), R(closure), U8(1), /* 117 S> */ B(CallRuntime), U16(Runtime::k_GetSuperConstructor), R(1), U8(1),
B(Star), R(2), B(Star), R(2),
B(Ldar), R(new_target), B(Ldar), R(0),
/* 117 E> */ B(New), R(2), R(0), U8(0), U8(0), /* 117 E> */ B(New), R(2), R(0), U8(0), U8(0),
B(Star), R(2), B(Star), R(2),
B(Ldar), R(this), B(Ldar), R(this),
......
...@@ -12,9 +12,10 @@ snippet: " ...@@ -12,9 +12,10 @@ snippet: "
" "
frame size: 1 frame size: 1
parameter count: 1 parameter count: 1
bytecode array length: 7 bytecode array length: 9
bytecodes: [ bytecodes: [
B(Mov), R(new_target), R(0), B(Mov), R(new_target), R(0),
B(Ldar), R(new_target),
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 34 S> */ B(Ldar), R(0), /* 34 S> */ B(Ldar), R(0),
/* 53 S> */ B(Return), /* 53 S> */ B(Return),
...@@ -30,9 +31,10 @@ snippet: " ...@@ -30,9 +31,10 @@ snippet: "
" "
frame size: 1 frame size: 1
parameter count: 1 parameter count: 1
bytecode array length: 6 bytecode array length: 8
bytecodes: [ bytecodes: [
B(Mov), R(new_target), R(0), B(Mov), R(new_target), R(0),
B(Ldar), R(new_target),
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 34 S> */ B(LdaUndefined), /* 34 S> */ B(LdaUndefined),
/* 46 S> */ B(Return), /* 46 S> */ B(Return),
......
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax --ignition-staging --turbo
class Base {}
class Subclass extends Base {
constructor() {
%DeoptimizeNow();
super();
}
}
new Subclass();
new Subclass();
%OptimizeFunctionOnNextCall(Subclass);
new Subclass();
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