Commit 8ff8c110 authored by Sigurd Schneider's avatar Sigurd Schneider Committed by Commit Bot

[turbofan] Thread feedback through to deoptimization entries

Bug: v8:7127
Change-Id: Iec65ead1540289aa99f496fd66595f2de88db68c
Reviewed-on: https://chromium-review.googlesource.com/817417Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50062}
parent e2ce2e0a
...@@ -300,7 +300,8 @@ void VisitBinop(InstructionSelector* selector, Node* node, ...@@ -300,7 +300,8 @@ void VisitBinop(InstructionSelector* selector, Node* node,
opcode = cont->Encode(opcode); opcode = cont->Encode(opcode);
if (cont->IsDeoptimize()) { if (cont->IsDeoptimize()) {
selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs,
cont->kind(), cont->reason(), cont->frame_state()); cont->kind(), cont->reason(), cont->feedback(),
cont->frame_state());
} else if (cont->IsTrap()) { } else if (cont->IsTrap()) {
inputs[input_count++] = g.UseImmediate(cont->trap_id()); inputs[input_count++] = g.UseImmediate(cont->trap_id());
selector->Emit(opcode, output_count, outputs, input_count, inputs); selector->Emit(opcode, output_count, outputs, input_count, inputs);
...@@ -950,7 +951,8 @@ void VisitShift(InstructionSelector* selector, Node* node, ...@@ -950,7 +951,8 @@ void VisitShift(InstructionSelector* selector, Node* node,
opcode = cont->Encode(opcode); opcode = cont->Encode(opcode);
if (cont->IsDeoptimize()) { if (cont->IsDeoptimize()) {
selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs,
cont->kind(), cont->reason(), cont->frame_state()); cont->kind(), cont->reason(), cont->feedback(),
cont->frame_state());
} else if (cont->IsTrap()) { } else if (cont->IsTrap()) {
inputs[input_count++] = g.UseImmediate(cont->trap_id()); inputs[input_count++] = g.UseImmediate(cont->trap_id());
selector->Emit(opcode, output_count, outputs, input_count, inputs); selector->Emit(opcode, output_count, outputs, input_count, inputs);
...@@ -1313,7 +1315,8 @@ void EmitInt32MulWithOverflow(InstructionSelector* selector, Node* node, ...@@ -1313,7 +1315,8 @@ void EmitInt32MulWithOverflow(InstructionSelector* selector, Node* node,
} else if (cont->IsDeoptimize()) { } else if (cont->IsDeoptimize()) {
InstructionOperand in[] = {temp_operand, result_operand, shift_31}; InstructionOperand in[] = {temp_operand, result_operand, shift_31};
selector->EmitDeoptimize(opcode, 0, nullptr, 3, in, cont->kind(), selector->EmitDeoptimize(opcode, 0, nullptr, 3, in, cont->kind(),
cont->reason(), cont->frame_state()); cont->reason(), cont->feedback(),
cont->frame_state());
} else if (cont->IsSet()) { } else if (cont->IsSet()) {
selector->Emit(opcode, g.DefineAsRegister(cont->result()), temp_operand, selector->Emit(opcode, g.DefineAsRegister(cont->result()), temp_operand,
result_operand, shift_31); result_operand, shift_31);
...@@ -1590,7 +1593,8 @@ void VisitCompare(InstructionSelector* selector, InstructionCode opcode, ...@@ -1590,7 +1593,8 @@ void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
g.Label(cont->true_block()), g.Label(cont->false_block())); g.Label(cont->true_block()), g.Label(cont->false_block()));
} else if (cont->IsDeoptimize()) { } else if (cont->IsDeoptimize()) {
selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, cont->kind(), selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, cont->kind(),
cont->reason(), cont->frame_state()); cont->reason(), cont->feedback(),
cont->frame_state());
} else if (cont->IsSet()) { } else if (cont->IsSet()) {
selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right);
} else { } else {
...@@ -1785,7 +1789,8 @@ void VisitWordCompare(InstructionSelector* selector, Node* node, ...@@ -1785,7 +1789,8 @@ void VisitWordCompare(InstructionSelector* selector, Node* node,
opcode = cont->Encode(opcode); opcode = cont->Encode(opcode);
if (cont->IsDeoptimize()) { if (cont->IsDeoptimize()) {
selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs,
cont->kind(), cont->reason(), cont->frame_state()); cont->kind(), cont->reason(), cont->feedback(),
cont->frame_state());
} else if (cont->IsTrap()) { } else if (cont->IsTrap()) {
inputs[input_count++] = g.UseImmediate(cont->trap_id()); inputs[input_count++] = g.UseImmediate(cont->trap_id());
selector->Emit(opcode, output_count, outputs, input_count, inputs); selector->Emit(opcode, output_count, outputs, input_count, inputs);
...@@ -1944,7 +1949,8 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user, ...@@ -1944,7 +1949,8 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user,
g.Label(cont->true_block()), g.Label(cont->false_block())); g.Label(cont->true_block()), g.Label(cont->false_block()));
} else if (cont->IsDeoptimize()) { } else if (cont->IsDeoptimize()) {
selector->EmitDeoptimize(opcode, g.NoOutput(), value_operand, value_operand, selector->EmitDeoptimize(opcode, g.NoOutput(), value_operand, value_operand,
cont->kind(), cont->reason(), cont->frame_state()); cont->kind(), cont->reason(), cont->feedback(),
cont->frame_state());
} else if (cont->IsSet()) { } else if (cont->IsSet()) {
selector->Emit(opcode, g.DefineAsRegister(cont->result()), value_operand, selector->Emit(opcode, g.DefineAsRegister(cont->result()), value_operand,
value_operand); value_operand);
...@@ -1966,14 +1972,14 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, ...@@ -1966,14 +1972,14 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
void InstructionSelector::VisitDeoptimizeIf(Node* node) { void InstructionSelector::VisitDeoptimizeIf(Node* node) {
DeoptimizeParameters p = DeoptimizeParametersOf(node->op()); DeoptimizeParameters p = DeoptimizeParametersOf(node->op());
FlagsContinuation cont = FlagsContinuation::ForDeoptimize( FlagsContinuation cont = FlagsContinuation::ForDeoptimize(
kNotEqual, p.kind(), p.reason(), node->InputAt(1)); kNotEqual, p.kind(), p.reason(), p.feedback(), node->InputAt(1));
VisitWordCompareZero(this, node, node->InputAt(0), &cont); VisitWordCompareZero(this, node, node->InputAt(0), &cont);
} }
void InstructionSelector::VisitDeoptimizeUnless(Node* node) { void InstructionSelector::VisitDeoptimizeUnless(Node* node) {
DeoptimizeParameters p = DeoptimizeParametersOf(node->op()); DeoptimizeParameters p = DeoptimizeParametersOf(node->op());
FlagsContinuation cont = FlagsContinuation::ForDeoptimize( FlagsContinuation cont = FlagsContinuation::ForDeoptimize(
kEqual, p.kind(), p.reason(), node->InputAt(1)); kEqual, p.kind(), p.reason(), p.feedback(), node->InputAt(1));
VisitWordCompareZero(this, node, node->InputAt(0), &cont); VisitWordCompareZero(this, node, node->InputAt(0), &cont);
} }
......
...@@ -488,7 +488,8 @@ void VisitBinop(InstructionSelector* selector, Node* node, ...@@ -488,7 +488,8 @@ void VisitBinop(InstructionSelector* selector, Node* node,
opcode = cont->Encode(opcode); opcode = cont->Encode(opcode);
if (cont->IsDeoptimize()) { if (cont->IsDeoptimize()) {
selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs,
cont->kind(), cont->reason(), cont->frame_state()); cont->kind(), cont->reason(), cont->feedback(),
cont->frame_state());
} else if (cont->IsTrap()) { } else if (cont->IsTrap()) {
inputs[input_count++] = g.UseImmediate(cont->trap_id()); inputs[input_count++] = g.UseImmediate(cont->trap_id());
selector->Emit(opcode, output_count, outputs, input_count, inputs); selector->Emit(opcode, output_count, outputs, input_count, inputs);
...@@ -1430,7 +1431,8 @@ void EmitInt32MulWithOverflow(InstructionSelector* selector, Node* node, ...@@ -1430,7 +1431,8 @@ void EmitInt32MulWithOverflow(InstructionSelector* selector, Node* node,
} else if (cont->IsDeoptimize()) { } else if (cont->IsDeoptimize()) {
InstructionOperand in[] = {result, result}; InstructionOperand in[] = {result, result};
selector->EmitDeoptimize(opcode, 0, nullptr, 2, in, cont->kind(), selector->EmitDeoptimize(opcode, 0, nullptr, 2, in, cont->kind(),
cont->reason(), cont->frame_state()); cont->reason(), cont->feedback(),
cont->frame_state());
} else if (cont->IsSet()) { } else if (cont->IsSet()) {
selector->Emit(opcode, g.DefineAsRegister(cont->result()), result, result); selector->Emit(opcode, g.DefineAsRegister(cont->result()), result, result);
} else { } else {
...@@ -1786,7 +1788,8 @@ void VisitCompare(InstructionSelector* selector, InstructionCode opcode, ...@@ -1786,7 +1788,8 @@ void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
g.Label(cont->true_block()), g.Label(cont->false_block())); g.Label(cont->true_block()), g.Label(cont->false_block()));
} else if (cont->IsDeoptimize()) { } else if (cont->IsDeoptimize()) {
selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, cont->kind(), selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, cont->kind(),
cont->reason(), cont->frame_state()); cont->reason(), cont->feedback(),
cont->frame_state());
} else if (cont->IsSet()) { } else if (cont->IsSet()) {
selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right);
} else { } else {
...@@ -1954,7 +1957,8 @@ void EmitBranchOrDeoptimize(InstructionSelector* selector, ...@@ -1954,7 +1957,8 @@ void EmitBranchOrDeoptimize(InstructionSelector* selector,
} else { } else {
DCHECK(cont->IsDeoptimize()); DCHECK(cont->IsDeoptimize());
selector->EmitDeoptimize(cont->Encode(opcode), g.NoOutput(), value, selector->EmitDeoptimize(cont->Encode(opcode), g.NoOutput(), value,
cont->kind(), cont->reason(), cont->frame_state()); cont->kind(), cont->reason(), cont->feedback(),
cont->frame_state());
} }
} }
...@@ -2331,7 +2335,8 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user, ...@@ -2331,7 +2335,8 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user,
} else if (cont->IsDeoptimize()) { } else if (cont->IsDeoptimize()) {
selector->EmitDeoptimize(cont->Encode(kArm64Tst32), g.NoOutput(), selector->EmitDeoptimize(cont->Encode(kArm64Tst32), g.NoOutput(),
g.UseRegister(value), g.UseRegister(value), g.UseRegister(value), g.UseRegister(value),
cont->kind(), cont->reason(), cont->frame_state()); cont->kind(), cont->reason(), cont->feedback(),
cont->frame_state());
} else { } else {
DCHECK(cont->IsTrap()); DCHECK(cont->IsTrap());
selector->Emit(cont->Encode(kArm64Tst32), g.NoOutput(), selector->Emit(cont->Encode(kArm64Tst32), g.NoOutput(),
...@@ -2351,14 +2356,14 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, ...@@ -2351,14 +2356,14 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
void InstructionSelector::VisitDeoptimizeIf(Node* node) { void InstructionSelector::VisitDeoptimizeIf(Node* node) {
DeoptimizeParameters p = DeoptimizeParametersOf(node->op()); DeoptimizeParameters p = DeoptimizeParametersOf(node->op());
FlagsContinuation cont = FlagsContinuation::ForDeoptimize( FlagsContinuation cont = FlagsContinuation::ForDeoptimize(
kNotEqual, p.kind(), p.reason(), node->InputAt(1)); kNotEqual, p.kind(), p.reason(), p.feedback(), node->InputAt(1));
VisitWordCompareZero(this, node, node->InputAt(0), &cont); VisitWordCompareZero(this, node, node->InputAt(0), &cont);
} }
void InstructionSelector::VisitDeoptimizeUnless(Node* node) { void InstructionSelector::VisitDeoptimizeUnless(Node* node) {
DeoptimizeParameters p = DeoptimizeParametersOf(node->op()); DeoptimizeParameters p = DeoptimizeParametersOf(node->op());
FlagsContinuation cont = FlagsContinuation::ForDeoptimize( FlagsContinuation cont = FlagsContinuation::ForDeoptimize(
kEqual, p.kind(), p.reason(), node->InputAt(1)); kEqual, p.kind(), p.reason(), p.feedback(), node->InputAt(1));
VisitWordCompareZero(this, node, node->InputAt(0), &cont); VisitWordCompareZero(this, node, node->InputAt(0), &cont);
} }
......
...@@ -825,10 +825,10 @@ const Operator* CommonOperatorBuilder::Branch(BranchHint hint) { ...@@ -825,10 +825,10 @@ const Operator* CommonOperatorBuilder::Branch(BranchHint hint) {
const Operator* CommonOperatorBuilder::Deoptimize( const Operator* CommonOperatorBuilder::Deoptimize(
DeoptimizeKind kind, DeoptimizeReason reason, DeoptimizeKind kind, DeoptimizeReason reason,
VectorSlotPair const& feedback) { VectorSlotPair const& feedback) {
#define CACHED_DEOPTIMIZE(Kind, Reason) \ #define CACHED_DEOPTIMIZE(Kind, Reason) \
if (kind == DeoptimizeKind::k##Kind && \ if (kind == DeoptimizeKind::k##Kind && \
reason == DeoptimizeReason::k##Reason) { \ reason == DeoptimizeReason::k##Reason && !feedback.IsValid()) { \
return &cache_.kDeoptimize##Kind##Reason##Operator; \ return &cache_.kDeoptimize##Kind##Reason##Operator; \
} }
CACHED_DEOPTIMIZE_LIST(CACHED_DEOPTIMIZE) CACHED_DEOPTIMIZE_LIST(CACHED_DEOPTIMIZE)
#undef CACHED_DEOPTIMIZE #undef CACHED_DEOPTIMIZE
...@@ -845,10 +845,10 @@ const Operator* CommonOperatorBuilder::Deoptimize( ...@@ -845,10 +845,10 @@ const Operator* CommonOperatorBuilder::Deoptimize(
const Operator* CommonOperatorBuilder::DeoptimizeIf( const Operator* CommonOperatorBuilder::DeoptimizeIf(
DeoptimizeKind kind, DeoptimizeReason reason, DeoptimizeKind kind, DeoptimizeReason reason,
VectorSlotPair const& feedback) { VectorSlotPair const& feedback) {
#define CACHED_DEOPTIMIZE_IF(Kind, Reason) \ #define CACHED_DEOPTIMIZE_IF(Kind, Reason) \
if (kind == DeoptimizeKind::k##Kind && \ if (kind == DeoptimizeKind::k##Kind && \
reason == DeoptimizeReason::k##Reason) { \ reason == DeoptimizeReason::k##Reason && !feedback.IsValid()) { \
return &cache_.kDeoptimizeIf##Kind##Reason##Operator; \ return &cache_.kDeoptimizeIf##Kind##Reason##Operator; \
} }
CACHED_DEOPTIMIZE_IF_LIST(CACHED_DEOPTIMIZE_IF) CACHED_DEOPTIMIZE_IF_LIST(CACHED_DEOPTIMIZE_IF)
#undef CACHED_DEOPTIMIZE_IF #undef CACHED_DEOPTIMIZE_IF
...@@ -865,10 +865,10 @@ const Operator* CommonOperatorBuilder::DeoptimizeIf( ...@@ -865,10 +865,10 @@ const Operator* CommonOperatorBuilder::DeoptimizeIf(
const Operator* CommonOperatorBuilder::DeoptimizeUnless( const Operator* CommonOperatorBuilder::DeoptimizeUnless(
DeoptimizeKind kind, DeoptimizeReason reason, DeoptimizeKind kind, DeoptimizeReason reason,
VectorSlotPair const& feedback) { VectorSlotPair const& feedback) {
#define CACHED_DEOPTIMIZE_UNLESS(Kind, Reason) \ #define CACHED_DEOPTIMIZE_UNLESS(Kind, Reason) \
if (kind == DeoptimizeKind::k##Kind && \ if (kind == DeoptimizeKind::k##Kind && \
reason == DeoptimizeReason::k##Reason) { \ reason == DeoptimizeReason::k##Reason && !feedback.IsValid()) { \
return &cache_.kDeoptimizeUnless##Kind##Reason##Operator; \ return &cache_.kDeoptimizeUnless##Kind##Reason##Operator; \
} }
CACHED_DEOPTIMIZE_UNLESS_LIST(CACHED_DEOPTIMIZE_UNLESS) CACHED_DEOPTIMIZE_UNLESS_LIST(CACHED_DEOPTIMIZE_UNLESS)
#undef CACHED_DEOPTIMIZE_UNLESS #undef CACHED_DEOPTIMIZE_UNLESS
...@@ -1401,6 +1401,23 @@ CommonOperatorBuilder::CreateFrameStateFunctionInfo( ...@@ -1401,6 +1401,23 @@ CommonOperatorBuilder::CreateFrameStateFunctionInfo(
FrameStateFunctionInfo(type, parameter_count, local_count, shared_info); FrameStateFunctionInfo(type, parameter_count, local_count, shared_info);
} }
#undef COMMON_CACHED_OP_LIST
#undef CACHED_RETURN_LIST
#undef CACHED_END_LIST
#undef CACHED_EFFECT_PHI_LIST
#undef CACHED_INDUCTION_VARIABLE_PHI_LIST
#undef CACHED_LOOP_LIST
#undef CACHED_MERGE_LIST
#undef CACHED_DEOPTIMIZE_LIST
#undef CACHED_DEOPTIMIZE_IF_LIST
#undef CACHED_DEOPTIMIZE_UNLESS_LIST
#undef CACHED_TRAP_IF_LIST
#undef CACHED_TRAP_UNLESS_LIST
#undef CACHED_PARAMETER_LIST
#undef CACHED_PHI_LIST
#undef CACHED_PROJECTION_LIST
#undef CACHED_STATE_VALUES_LIST
} // namespace compiler } // namespace compiler
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -524,7 +524,8 @@ void VisitBinop(InstructionSelector* selector, Node* node, ...@@ -524,7 +524,8 @@ void VisitBinop(InstructionSelector* selector, Node* node,
opcode = cont->Encode(opcode); opcode = cont->Encode(opcode);
if (cont->IsDeoptimize()) { if (cont->IsDeoptimize()) {
selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs,
cont->kind(), cont->reason(), cont->frame_state()); cont->kind(), cont->reason(), cont->feedback(),
cont->frame_state());
} else { } else {
selector->Emit(opcode, output_count, outputs, input_count, inputs); selector->Emit(opcode, output_count, outputs, input_count, inputs);
} }
...@@ -1132,7 +1133,8 @@ void VisitCompareWithMemoryOperand(InstructionSelector* selector, ...@@ -1132,7 +1133,8 @@ void VisitCompareWithMemoryOperand(InstructionSelector* selector,
selector->Emit(opcode, 0, nullptr, input_count, inputs); selector->Emit(opcode, 0, nullptr, input_count, inputs);
} else if (cont->IsDeoptimize()) { } else if (cont->IsDeoptimize()) {
selector->EmitDeoptimize(opcode, 0, nullptr, input_count, inputs, selector->EmitDeoptimize(opcode, 0, nullptr, input_count, inputs,
cont->kind(), cont->reason(), cont->frame_state()); cont->kind(), cont->reason(), cont->feedback(),
cont->frame_state());
} else if (cont->IsSet()) { } else if (cont->IsSet()) {
InstructionOperand output = g.DefineAsRegister(cont->result()); InstructionOperand output = g.DefineAsRegister(cont->result());
selector->Emit(opcode, 1, &output, input_count, inputs); selector->Emit(opcode, 1, &output, input_count, inputs);
...@@ -1154,7 +1156,8 @@ void VisitCompare(InstructionSelector* selector, InstructionCode opcode, ...@@ -1154,7 +1156,8 @@ void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
g.Label(cont->true_block()), g.Label(cont->false_block())); g.Label(cont->true_block()), g.Label(cont->false_block()));
} else if (cont->IsDeoptimize()) { } else if (cont->IsDeoptimize()) {
selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, cont->kind(), selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, cont->kind(),
cont->reason(), cont->frame_state()); cont->reason(), cont->feedback(),
cont->frame_state());
} else if (cont->IsSet()) { } else if (cont->IsSet()) {
selector->Emit(opcode, g.DefineAsByteRegister(cont->result()), left, right); selector->Emit(opcode, g.DefineAsByteRegister(cont->result()), left, right);
} else { } else {
...@@ -1340,7 +1343,8 @@ void VisitWordCompare(InstructionSelector* selector, Node* node, ...@@ -1340,7 +1343,8 @@ void VisitWordCompare(InstructionSelector* selector, Node* node,
g.Label(cont->false_block())); g.Label(cont->false_block()));
} else if (cont->IsDeoptimize()) { } else if (cont->IsDeoptimize()) {
selector->EmitDeoptimize(opcode, 0, nullptr, 0, nullptr, cont->kind(), selector->EmitDeoptimize(opcode, 0, nullptr, 0, nullptr, cont->kind(),
cont->reason(), cont->frame_state()); cont->reason(), cont->feedback(),
cont->frame_state());
} else { } else {
DCHECK(cont->IsSet()); DCHECK(cont->IsSet());
selector->Emit(opcode, g.DefineAsRegister(cont->result())); selector->Emit(opcode, g.DefineAsRegister(cont->result()));
...@@ -1454,14 +1458,14 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, ...@@ -1454,14 +1458,14 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
void InstructionSelector::VisitDeoptimizeIf(Node* node) { void InstructionSelector::VisitDeoptimizeIf(Node* node) {
DeoptimizeParameters p = DeoptimizeParametersOf(node->op()); DeoptimizeParameters p = DeoptimizeParametersOf(node->op());
FlagsContinuation cont = FlagsContinuation::ForDeoptimize( FlagsContinuation cont = FlagsContinuation::ForDeoptimize(
kNotEqual, p.kind(), p.reason(), node->InputAt(1)); kNotEqual, p.kind(), p.reason(), p.feedback(), node->InputAt(1));
VisitWordCompareZero(this, node, node->InputAt(0), &cont); VisitWordCompareZero(this, node, node->InputAt(0), &cont);
} }
void InstructionSelector::VisitDeoptimizeUnless(Node* node) { void InstructionSelector::VisitDeoptimizeUnless(Node* node) {
DeoptimizeParameters p = DeoptimizeParametersOf(node->op()); DeoptimizeParameters p = DeoptimizeParametersOf(node->op());
FlagsContinuation cont = FlagsContinuation::ForDeoptimize( FlagsContinuation cont = FlagsContinuation::ForDeoptimize(
kEqual, p.kind(), p.reason(), node->InputAt(1)); kEqual, p.kind(), p.reason(), p.feedback(), node->InputAt(1));
VisitWordCompareZero(this, node, node->InputAt(0), &cont); VisitWordCompareZero(this, node, node->InputAt(0), &cont);
} }
......
...@@ -350,8 +350,9 @@ class FlagsContinuation final { ...@@ -350,8 +350,9 @@ class FlagsContinuation final {
static FlagsContinuation ForDeoptimize(FlagsCondition condition, static FlagsContinuation ForDeoptimize(FlagsCondition condition,
DeoptimizeKind kind, DeoptimizeKind kind,
DeoptimizeReason reason, DeoptimizeReason reason,
VectorSlotPair const& feedback,
Node* frame_state) { Node* frame_state) {
return FlagsContinuation(condition, kind, reason, frame_state); return FlagsContinuation(condition, kind, reason, feedback, frame_state);
} }
// Creates a new flags continuation for a boolean value. // Creates a new flags continuation for a boolean value.
...@@ -382,6 +383,10 @@ class FlagsContinuation final { ...@@ -382,6 +383,10 @@ class FlagsContinuation final {
DCHECK(IsDeoptimize()); DCHECK(IsDeoptimize());
return reason_; return reason_;
} }
VectorSlotPair const& feedback() const {
DCHECK(IsDeoptimize());
return feedback_;
}
Node* frame_state() const { Node* frame_state() const {
DCHECK(IsDeoptimize()); DCHECK(IsDeoptimize());
return frame_state_or_result_; return frame_state_or_result_;
...@@ -452,11 +457,13 @@ class FlagsContinuation final { ...@@ -452,11 +457,13 @@ class FlagsContinuation final {
private: private:
FlagsContinuation(FlagsCondition condition, DeoptimizeKind kind, FlagsContinuation(FlagsCondition condition, DeoptimizeKind kind,
DeoptimizeReason reason, Node* frame_state) DeoptimizeReason reason, VectorSlotPair const& feedback,
Node* frame_state)
: mode_(kFlags_deoptimize), : mode_(kFlags_deoptimize),
condition_(condition), condition_(condition),
kind_(kind), kind_(kind),
reason_(reason), reason_(reason),
feedback_(feedback),
frame_state_or_result_(frame_state) { frame_state_or_result_(frame_state) {
DCHECK_NOT_NULL(frame_state); DCHECK_NOT_NULL(frame_state);
} }
...@@ -480,6 +487,7 @@ class FlagsContinuation final { ...@@ -480,6 +487,7 @@ class FlagsContinuation final {
FlagsCondition condition_; FlagsCondition condition_;
DeoptimizeKind kind_; // Only valid if mode_ == kFlags_deoptimize DeoptimizeKind kind_; // Only valid if mode_ == kFlags_deoptimize
DeoptimizeReason reason_; // Only valid if mode_ == kFlags_deoptimize DeoptimizeReason reason_; // Only valid if mode_ == kFlags_deoptimize
VectorSlotPair feedback_; // Only valid if mode_ == kFlags_deoptimize
Node* frame_state_or_result_; // Only valid if mode_ == kFlags_deoptimize Node* frame_state_or_result_; // Only valid if mode_ == kFlags_deoptimize
// or mode_ == kFlags_set. // or mode_ == kFlags_set.
BasicBlock* true_block_; // Only valid if mode_ == kFlags_branch. BasicBlock* true_block_; // Only valid if mode_ == kFlags_branch.
......
...@@ -814,7 +814,7 @@ void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer, ...@@ -814,7 +814,7 @@ void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer,
int const state_id = sequence()->AddDeoptimizationEntry( int const state_id = sequence()->AddDeoptimizationEntry(
buffer->frame_state_descriptor, DeoptimizeKind::kLazy, buffer->frame_state_descriptor, DeoptimizeKind::kLazy,
DeoptimizeReason::kNoReason); DeoptimizeReason::kNoReason, VectorSlotPair());
buffer->instruction_args.push_back(g.TempImmediate(state_id)); buffer->instruction_args.push_back(g.TempImmediate(state_id));
StateObjectDeduplicator deduplicator(instruction_zone()); StateObjectDeduplicator deduplicator(instruction_zone());
...@@ -1032,7 +1032,7 @@ void InstructionSelector::VisitControl(BasicBlock* block) { ...@@ -1032,7 +1032,7 @@ void InstructionSelector::VisitControl(BasicBlock* block) {
case BasicBlock::kDeoptimize: { case BasicBlock::kDeoptimize: {
DeoptimizeParameters p = DeoptimizeParametersOf(input->op()); DeoptimizeParameters p = DeoptimizeParametersOf(input->op());
Node* value = input->InputAt(0); Node* value = input->InputAt(0);
return VisitDeoptimize(p.kind(), p.reason(), value); return VisitDeoptimize(p.kind(), p.reason(), p.feedback(), value);
} }
case BasicBlock::kThrow: case BasicBlock::kThrow:
DCHECK_EQ(IrOpcode::kThrow, input->opcode()); DCHECK_EQ(IrOpcode::kThrow, input->opcode());
...@@ -2539,29 +2539,31 @@ void InstructionSelector::VisitReturn(Node* ret) { ...@@ -2539,29 +2539,31 @@ void InstructionSelector::VisitReturn(Node* ret) {
Instruction* InstructionSelector::EmitDeoptimize( Instruction* InstructionSelector::EmitDeoptimize(
InstructionCode opcode, InstructionOperand output, InstructionOperand a, InstructionCode opcode, InstructionOperand output, InstructionOperand a,
DeoptimizeKind kind, DeoptimizeReason reason, Node* frame_state) { DeoptimizeKind kind, DeoptimizeReason reason,
VectorSlotPair const& feedback, Node* frame_state) {
size_t output_count = output.IsInvalid() ? 0 : 1; size_t output_count = output.IsInvalid() ? 0 : 1;
InstructionOperand inputs[] = {a}; InstructionOperand inputs[] = {a};
size_t input_count = arraysize(inputs); size_t input_count = arraysize(inputs);
return EmitDeoptimize(opcode, output_count, &output, input_count, inputs, return EmitDeoptimize(opcode, output_count, &output, input_count, inputs,
kind, reason, frame_state); kind, reason, feedback, frame_state);
} }
Instruction* InstructionSelector::EmitDeoptimize( Instruction* InstructionSelector::EmitDeoptimize(
InstructionCode opcode, InstructionOperand output, InstructionOperand a, InstructionCode opcode, InstructionOperand output, InstructionOperand a,
InstructionOperand b, DeoptimizeKind kind, DeoptimizeReason reason, InstructionOperand b, DeoptimizeKind kind, DeoptimizeReason reason,
Node* frame_state) { VectorSlotPair const& feedback, Node* frame_state) {
size_t output_count = output.IsInvalid() ? 0 : 1; size_t output_count = output.IsInvalid() ? 0 : 1;
InstructionOperand inputs[] = {a, b}; InstructionOperand inputs[] = {a, b};
size_t input_count = arraysize(inputs); size_t input_count = arraysize(inputs);
return EmitDeoptimize(opcode, output_count, &output, input_count, inputs, return EmitDeoptimize(opcode, output_count, &output, input_count, inputs,
kind, reason, frame_state); kind, reason, feedback, frame_state);
} }
Instruction* InstructionSelector::EmitDeoptimize( Instruction* InstructionSelector::EmitDeoptimize(
InstructionCode opcode, size_t output_count, InstructionOperand* outputs, InstructionCode opcode, size_t output_count, InstructionOperand* outputs,
size_t input_count, InstructionOperand* inputs, DeoptimizeKind kind, size_t input_count, InstructionOperand* inputs, DeoptimizeKind kind,
DeoptimizeReason reason, Node* frame_state) { DeoptimizeReason reason, VectorSlotPair const& feedback,
Node* frame_state) {
OperandGenerator g(this); OperandGenerator g(this);
FrameStateDescriptor* const descriptor = GetFrameStateDescriptor(frame_state); FrameStateDescriptor* const descriptor = GetFrameStateDescriptor(frame_state);
InstructionOperandVector args(instruction_zone()); InstructionOperandVector args(instruction_zone());
...@@ -2572,7 +2574,7 @@ Instruction* InstructionSelector::EmitDeoptimize( ...@@ -2572,7 +2574,7 @@ Instruction* InstructionSelector::EmitDeoptimize(
opcode |= MiscField::encode(static_cast<int>(input_count)); opcode |= MiscField::encode(static_cast<int>(input_count));
DCHECK_NE(DeoptimizeKind::kLazy, kind); DCHECK_NE(DeoptimizeKind::kLazy, kind);
int const state_id = int const state_id =
sequence()->AddDeoptimizationEntry(descriptor, kind, reason); sequence()->AddDeoptimizationEntry(descriptor, kind, reason, feedback);
args.push_back(g.TempImmediate(state_id)); args.push_back(g.TempImmediate(state_id));
StateObjectDeduplicator deduplicator(instruction_zone()); StateObjectDeduplicator deduplicator(instruction_zone());
AddInputsToFrameStateDescriptor(descriptor, frame_state, &g, &deduplicator, AddInputsToFrameStateDescriptor(descriptor, frame_state, &g, &deduplicator,
...@@ -2590,8 +2592,10 @@ void InstructionSelector::EmitIdentity(Node* node) { ...@@ -2590,8 +2592,10 @@ void InstructionSelector::EmitIdentity(Node* node) {
void InstructionSelector::VisitDeoptimize(DeoptimizeKind kind, void InstructionSelector::VisitDeoptimize(DeoptimizeKind kind,
DeoptimizeReason reason, DeoptimizeReason reason,
VectorSlotPair const& feedback,
Node* value) { Node* value) {
EmitDeoptimize(kArchDeoptimize, 0, nullptr, 0, nullptr, kind, reason, value); EmitDeoptimize(kArchDeoptimize, 0, nullptr, 0, nullptr, kind, reason,
feedback, value);
} }
void InstructionSelector::VisitThrow(Node* node) { void InstructionSelector::VisitThrow(Node* node) {
......
...@@ -112,15 +112,20 @@ class V8_EXPORT_PRIVATE InstructionSelector final { ...@@ -112,15 +112,20 @@ class V8_EXPORT_PRIVATE InstructionSelector final {
Instruction* EmitDeoptimize(InstructionCode opcode, InstructionOperand output, Instruction* EmitDeoptimize(InstructionCode opcode, InstructionOperand output,
InstructionOperand a, DeoptimizeKind kind, InstructionOperand a, DeoptimizeKind kind,
DeoptimizeReason reason, Node* frame_state); DeoptimizeReason reason,
VectorSlotPair const& feedback,
Node* frame_state);
Instruction* EmitDeoptimize(InstructionCode opcode, InstructionOperand output, Instruction* EmitDeoptimize(InstructionCode opcode, InstructionOperand output,
InstructionOperand a, InstructionOperand b, InstructionOperand a, InstructionOperand b,
DeoptimizeKind kind, DeoptimizeReason reason, DeoptimizeKind kind, DeoptimizeReason reason,
VectorSlotPair const& feedback,
Node* frame_state); Node* frame_state);
Instruction* EmitDeoptimize(InstructionCode opcode, size_t output_count, Instruction* EmitDeoptimize(InstructionCode opcode, size_t output_count,
InstructionOperand* outputs, size_t input_count, InstructionOperand* outputs, size_t input_count,
InstructionOperand* inputs, DeoptimizeKind kind, InstructionOperand* inputs, DeoptimizeKind kind,
DeoptimizeReason reason, Node* frame_state); DeoptimizeReason reason,
VectorSlotPair const& feedback,
Node* frame_state);
// =========================================================================== // ===========================================================================
// ============== Architecture-independent CPU feature methods. ============== // ============== Architecture-independent CPU feature methods. ==============
...@@ -342,7 +347,7 @@ class V8_EXPORT_PRIVATE InstructionSelector final { ...@@ -342,7 +347,7 @@ class V8_EXPORT_PRIVATE InstructionSelector final {
void VisitBranch(Node* input, BasicBlock* tbranch, BasicBlock* fbranch); void VisitBranch(Node* input, BasicBlock* tbranch, BasicBlock* fbranch);
void VisitSwitch(Node* node, const SwitchInfo& sw); void VisitSwitch(Node* node, const SwitchInfo& sw);
void VisitDeoptimize(DeoptimizeKind kind, DeoptimizeReason reason, void VisitDeoptimize(DeoptimizeKind kind, DeoptimizeReason reason,
Node* value); VectorSlotPair const& feedback, Node* value);
void VisitReturn(Node* ret); void VisitReturn(Node* ret);
void VisitThrow(Node* node); void VisitThrow(Node* node);
void VisitRetain(Node* node); void VisitRetain(Node* node);
......
...@@ -927,10 +927,10 @@ void InstructionSequence::MarkAsRepresentation(MachineRepresentation rep, ...@@ -927,10 +927,10 @@ void InstructionSequence::MarkAsRepresentation(MachineRepresentation rep,
int InstructionSequence::AddDeoptimizationEntry( int InstructionSequence::AddDeoptimizationEntry(
FrameStateDescriptor* descriptor, DeoptimizeKind kind, FrameStateDescriptor* descriptor, DeoptimizeKind kind,
DeoptimizeReason reason) { DeoptimizeReason reason, VectorSlotPair const& feedback) {
int deoptimization_id = static_cast<int>(deoptimization_entries_.size()); int deoptimization_id = static_cast<int>(deoptimization_entries_.size());
deoptimization_entries_.push_back( deoptimization_entries_.push_back(
DeoptimizationEntry(descriptor, kind, reason)); DeoptimizationEntry(descriptor, kind, reason, feedback));
return deoptimization_id; return deoptimization_id;
} }
......
...@@ -1317,17 +1317,22 @@ class DeoptimizationEntry final { ...@@ -1317,17 +1317,22 @@ class DeoptimizationEntry final {
public: public:
DeoptimizationEntry() {} DeoptimizationEntry() {}
DeoptimizationEntry(FrameStateDescriptor* descriptor, DeoptimizeKind kind, DeoptimizationEntry(FrameStateDescriptor* descriptor, DeoptimizeKind kind,
DeoptimizeReason reason) DeoptimizeReason reason, VectorSlotPair const& feedback)
: descriptor_(descriptor), kind_(kind), reason_(reason) {} : descriptor_(descriptor),
kind_(kind),
reason_(reason),
feedback_(feedback) {}
FrameStateDescriptor* descriptor() const { return descriptor_; } FrameStateDescriptor* descriptor() const { return descriptor_; }
DeoptimizeKind kind() const { return kind_; } DeoptimizeKind kind() const { return kind_; }
DeoptimizeReason reason() const { return reason_; } DeoptimizeReason reason() const { return reason_; }
VectorSlotPair const& feedback() const { return feedback_; }
private: private:
FrameStateDescriptor* descriptor_ = nullptr; FrameStateDescriptor* descriptor_ = nullptr;
DeoptimizeKind kind_ = DeoptimizeKind::kEager; DeoptimizeKind kind_ = DeoptimizeKind::kEager;
DeoptimizeReason reason_ = DeoptimizeReason::kNoReason; DeoptimizeReason reason_ = DeoptimizeReason::kNoReason;
VectorSlotPair feedback_ = VectorSlotPair();
}; };
typedef ZoneVector<DeoptimizationEntry> DeoptimizationVector; typedef ZoneVector<DeoptimizationEntry> DeoptimizationVector;
...@@ -1586,7 +1591,8 @@ class V8_EXPORT_PRIVATE InstructionSequence final ...@@ -1586,7 +1591,8 @@ class V8_EXPORT_PRIVATE InstructionSequence final
} }
int AddDeoptimizationEntry(FrameStateDescriptor* descriptor, int AddDeoptimizationEntry(FrameStateDescriptor* descriptor,
DeoptimizeKind kind, DeoptimizeReason reason); DeoptimizeKind kind, DeoptimizeReason reason,
VectorSlotPair const& feedback);
DeoptimizationEntry const& GetDeoptimizationEntry(int deoptimization_id); DeoptimizationEntry const& GetDeoptimizationEntry(int deoptimization_id);
int GetDeoptimizationEntryCount() const { int GetDeoptimizationEntryCount() const {
return static_cast<int>(deoptimization_entries_.size()); return static_cast<int>(deoptimization_entries_.size());
......
...@@ -228,7 +228,8 @@ static void VisitBinop(InstructionSelector* selector, Node* node, ...@@ -228,7 +228,8 @@ static void VisitBinop(InstructionSelector* selector, Node* node,
opcode = cont->Encode(opcode); opcode = cont->Encode(opcode);
if (cont->IsDeoptimize()) { if (cont->IsDeoptimize()) {
selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs,
cont->kind(), cont->reason(), cont->frame_state()); cont->kind(), cont->reason(), cont->feedback(),
cont->frame_state());
} else { } else {
selector->Emit(opcode, output_count, outputs, input_count, inputs); selector->Emit(opcode, output_count, outputs, input_count, inputs);
} }
...@@ -1372,7 +1373,8 @@ static void VisitCompare(InstructionSelector* selector, InstructionCode opcode, ...@@ -1372,7 +1373,8 @@ static void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
g.Label(cont->true_block()), g.Label(cont->false_block())); g.Label(cont->true_block()), g.Label(cont->false_block()));
} else if (cont->IsDeoptimize()) { } else if (cont->IsDeoptimize()) {
selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, cont->kind(), selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, cont->kind(),
cont->reason(), cont->frame_state()); cont->reason(), cont->feedback(),
cont->frame_state());
} else if (cont->IsSet()) { } else if (cont->IsSet()) {
selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right);
} else { } else {
...@@ -1585,7 +1587,7 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user, ...@@ -1585,7 +1587,7 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user,
} else if (cont->IsDeoptimize()) { } else if (cont->IsDeoptimize()) {
selector->EmitDeoptimize(opcode, g.NoOutput(), value_operand, selector->EmitDeoptimize(opcode, g.NoOutput(), value_operand,
g.TempImmediate(0), cont->kind(), cont->reason(), g.TempImmediate(0), cont->kind(), cont->reason(),
cont->frame_state()); cont->feedback(), cont->frame_state());
} else if (cont->IsSet()) { } else if (cont->IsSet()) {
selector->Emit(opcode, g.DefineAsRegister(cont->result()), value_operand, selector->Emit(opcode, g.DefineAsRegister(cont->result()), value_operand,
g.TempImmediate(0)); g.TempImmediate(0));
...@@ -1607,14 +1609,14 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, ...@@ -1607,14 +1609,14 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
void InstructionSelector::VisitDeoptimizeIf(Node* node) { void InstructionSelector::VisitDeoptimizeIf(Node* node) {
DeoptimizeParameters p = DeoptimizeParametersOf(node->op()); DeoptimizeParameters p = DeoptimizeParametersOf(node->op());
FlagsContinuation cont = FlagsContinuation::ForDeoptimize( FlagsContinuation cont = FlagsContinuation::ForDeoptimize(
kNotEqual, p.kind(), p.reason(), node->InputAt(1)); kNotEqual, p.kind(), p.reason(), p.feedback(), node->InputAt(1));
VisitWordCompareZero(this, node, node->InputAt(0), &cont); VisitWordCompareZero(this, node, node->InputAt(0), &cont);
} }
void InstructionSelector::VisitDeoptimizeUnless(Node* node) { void InstructionSelector::VisitDeoptimizeUnless(Node* node) {
DeoptimizeParameters p = DeoptimizeParametersOf(node->op()); DeoptimizeParameters p = DeoptimizeParametersOf(node->op());
FlagsContinuation cont = FlagsContinuation::ForDeoptimize( FlagsContinuation cont = FlagsContinuation::ForDeoptimize(
kEqual, p.kind(), p.reason(), node->InputAt(1)); kEqual, p.kind(), p.reason(), p.feedback(), node->InputAt(1));
VisitWordCompareZero(this, node, node->InputAt(0), &cont); VisitWordCompareZero(this, node, node->InputAt(0), &cont);
} }
......
...@@ -323,7 +323,8 @@ static void VisitBinop(InstructionSelector* selector, Node* node, ...@@ -323,7 +323,8 @@ static void VisitBinop(InstructionSelector* selector, Node* node,
opcode = cont->Encode(opcode); opcode = cont->Encode(opcode);
if (cont->IsDeoptimize()) { if (cont->IsDeoptimize()) {
selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs,
cont->kind(), cont->reason(), cont->frame_state()); cont->kind(), cont->reason(), cont->feedback(),
cont->frame_state());
} else { } else {
selector->Emit(opcode, output_count, outputs, input_count, inputs); selector->Emit(opcode, output_count, outputs, input_count, inputs);
} }
...@@ -1877,7 +1878,8 @@ static void VisitCompare(InstructionSelector* selector, InstructionCode opcode, ...@@ -1877,7 +1878,8 @@ static void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
g.Label(cont->true_block()), g.Label(cont->false_block())); g.Label(cont->true_block()), g.Label(cont->false_block()));
} else if (cont->IsDeoptimize()) { } else if (cont->IsDeoptimize()) {
selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, cont->kind(), selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, cont->kind(),
cont->reason(), cont->frame_state()); cont->reason(), cont->feedback(),
cont->frame_state());
} else if (cont->IsSet()) { } else if (cont->IsSet()) {
selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right);
} else { } else {
...@@ -2094,7 +2096,7 @@ void EmitWordCompareZero(InstructionSelector* selector, Node* value, ...@@ -2094,7 +2096,7 @@ void EmitWordCompareZero(InstructionSelector* selector, Node* value,
} else if (cont->IsDeoptimize()) { } else if (cont->IsDeoptimize()) {
selector->EmitDeoptimize(opcode, g.NoOutput(), value_operand, selector->EmitDeoptimize(opcode, g.NoOutput(), value_operand,
g.TempImmediate(0), cont->kind(), cont->reason(), g.TempImmediate(0), cont->kind(), cont->reason(),
cont->frame_state()); cont->feedback(), cont->frame_state());
} else if (cont->IsTrap()) { } else if (cont->IsTrap()) {
selector->Emit(opcode, g.NoOutput(), value_operand, g.TempImmediate(0), selector->Emit(opcode, g.NoOutput(), value_operand, g.TempImmediate(0),
g.TempImmediate(cont->trap_id())); g.TempImmediate(cont->trap_id()));
...@@ -2234,14 +2236,14 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, ...@@ -2234,14 +2236,14 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
void InstructionSelector::VisitDeoptimizeIf(Node* node) { void InstructionSelector::VisitDeoptimizeIf(Node* node) {
DeoptimizeParameters p = DeoptimizeParametersOf(node->op()); DeoptimizeParameters p = DeoptimizeParametersOf(node->op());
FlagsContinuation cont = FlagsContinuation::ForDeoptimize( FlagsContinuation cont = FlagsContinuation::ForDeoptimize(
kNotEqual, p.kind(), p.reason(), node->InputAt(1)); kNotEqual, p.kind(), p.reason(), p.feedback(), node->InputAt(1));
VisitWordCompareZero(this, node, node->InputAt(0), &cont); VisitWordCompareZero(this, node, node->InputAt(0), &cont);
} }
void InstructionSelector::VisitDeoptimizeUnless(Node* node) { void InstructionSelector::VisitDeoptimizeUnless(Node* node) {
DeoptimizeParameters p = DeoptimizeParametersOf(node->op()); DeoptimizeParameters p = DeoptimizeParametersOf(node->op());
FlagsContinuation cont = FlagsContinuation::ForDeoptimize( FlagsContinuation cont = FlagsContinuation::ForDeoptimize(
kEqual, p.kind(), p.reason(), node->InputAt(1)); kEqual, p.kind(), p.reason(), p.feedback(), node->InputAt(1));
VisitWordCompareZero(this, node, node->InputAt(0), &cont); VisitWordCompareZero(this, node, node->InputAt(0), &cont);
} }
......
...@@ -154,7 +154,8 @@ void VisitBinop(InstructionSelector* selector, Node* node, ...@@ -154,7 +154,8 @@ void VisitBinop(InstructionSelector* selector, Node* node,
opcode = cont->Encode(opcode); opcode = cont->Encode(opcode);
if (cont->IsDeoptimize()) { if (cont->IsDeoptimize()) {
selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs,
cont->kind(), cont->reason(), cont->frame_state()); cont->kind(), cont->reason(), cont->feedback(),
cont->frame_state());
} else if (cont->IsTrap()) { } else if (cont->IsTrap()) {
inputs[input_count++] = g.UseImmediate(cont->trap_id()); inputs[input_count++] = g.UseImmediate(cont->trap_id());
selector->Emit(opcode, output_count, outputs, input_count, inputs); selector->Emit(opcode, output_count, outputs, input_count, inputs);
...@@ -1504,7 +1505,8 @@ void VisitCompare(InstructionSelector* selector, InstructionCode opcode, ...@@ -1504,7 +1505,8 @@ void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
g.Label(cont->true_block()), g.Label(cont->false_block())); g.Label(cont->true_block()), g.Label(cont->false_block()));
} else if (cont->IsDeoptimize()) { } else if (cont->IsDeoptimize()) {
selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, cont->kind(), selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, cont->kind(),
cont->reason(), cont->frame_state()); cont->reason(), cont->feedback(),
cont->frame_state());
} else if (cont->IsSet()) { } else if (cont->IsSet()) {
selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right);
} else { } else {
...@@ -1751,14 +1753,14 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, ...@@ -1751,14 +1753,14 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
void InstructionSelector::VisitDeoptimizeIf(Node* node) { void InstructionSelector::VisitDeoptimizeIf(Node* node) {
DeoptimizeParameters p = DeoptimizeParametersOf(node->op()); DeoptimizeParameters p = DeoptimizeParametersOf(node->op());
FlagsContinuation cont = FlagsContinuation::ForDeoptimize( FlagsContinuation cont = FlagsContinuation::ForDeoptimize(
kNotEqual, p.kind(), p.reason(), node->InputAt(1)); kNotEqual, p.kind(), p.reason(), p.feedback(), node->InputAt(1));
VisitWord32CompareZero(this, node, node->InputAt(0), &cont); VisitWord32CompareZero(this, node, node->InputAt(0), &cont);
} }
void InstructionSelector::VisitDeoptimizeUnless(Node* node) { void InstructionSelector::VisitDeoptimizeUnless(Node* node) {
DeoptimizeParameters p = DeoptimizeParametersOf(node->op()); DeoptimizeParameters p = DeoptimizeParametersOf(node->op());
FlagsContinuation cont = FlagsContinuation::ForDeoptimize( FlagsContinuation cont = FlagsContinuation::ForDeoptimize(
kEqual, p.kind(), p.reason(), node->InputAt(1)); kEqual, p.kind(), p.reason(), p.feedback(), node->InputAt(1));
VisitWord32CompareZero(this, node, node->InputAt(0), &cont); VisitWord32CompareZero(this, node, node->InputAt(0), &cont);
} }
......
...@@ -613,7 +613,8 @@ void VisitUnaryOp(InstructionSelector* selector, Node* node, ...@@ -613,7 +613,8 @@ void VisitUnaryOp(InstructionSelector* selector, Node* node,
if (cont->IsDeoptimize()) { if (cont->IsDeoptimize()) {
selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs,
cont->kind(), cont->reason(), cont->frame_state()); cont->kind(), cont->reason(), cont->feedback(),
cont->frame_state());
} else if (cont->IsTrap()) { } else if (cont->IsTrap()) {
inputs[input_count++] = g.UseImmediate(cont->trap_id()); inputs[input_count++] = g.UseImmediate(cont->trap_id());
selector->Emit(opcode, output_count, outputs, input_count, inputs); selector->Emit(opcode, output_count, outputs, input_count, inputs);
...@@ -688,7 +689,8 @@ void VisitBinOp(InstructionSelector* selector, Node* node, ...@@ -688,7 +689,8 @@ void VisitBinOp(InstructionSelector* selector, Node* node,
if (cont->IsDeoptimize()) { if (cont->IsDeoptimize()) {
selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs,
cont->kind(), cont->reason(), cont->frame_state()); cont->kind(), cont->reason(), cont->feedback(),
cont->frame_state());
} else if (cont->IsTrap()) { } else if (cont->IsTrap()) {
inputs[input_count++] = g.UseImmediate(cont->trap_id()); inputs[input_count++] = g.UseImmediate(cont->trap_id());
selector->Emit(opcode, output_count, outputs, input_count, inputs); selector->Emit(opcode, output_count, outputs, input_count, inputs);
...@@ -1681,7 +1683,8 @@ void VisitCompare(InstructionSelector* selector, InstructionCode opcode, ...@@ -1681,7 +1683,8 @@ void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
g.Label(cont->true_block()), g.Label(cont->false_block())); g.Label(cont->true_block()), g.Label(cont->false_block()));
} else if (cont->IsDeoptimize()) { } else if (cont->IsDeoptimize()) {
selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, cont->kind(), selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, cont->kind(),
cont->reason(), cont->frame_state()); cont->reason(), cont->feedback(),
cont->frame_state());
} else if (cont->IsSet()) { } else if (cont->IsSet()) {
selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right);
} else { } else {
...@@ -1769,7 +1772,8 @@ void VisitWordCompare(InstructionSelector* selector, Node* node, ...@@ -1769,7 +1772,8 @@ void VisitWordCompare(InstructionSelector* selector, Node* node,
DCHECK(input_count <= 8 && output_count <= 1); DCHECK(input_count <= 8 && output_count <= 1);
if (cont->IsDeoptimize()) { if (cont->IsDeoptimize()) {
selector->EmitDeoptimize(opcode, 0, nullptr, input_count, inputs, selector->EmitDeoptimize(opcode, 0, nullptr, input_count, inputs,
cont->kind(), cont->reason(), cont->frame_state()); cont->kind(), cont->reason(), cont->feedback(),
cont->frame_state());
} else { } else {
selector->Emit(opcode, output_count, outputs, input_count, inputs); selector->Emit(opcode, output_count, outputs, input_count, inputs);
} }
...@@ -1874,7 +1878,8 @@ void VisitLoadAndTest(InstructionSelector* selector, InstructionCode opcode, ...@@ -1874,7 +1878,8 @@ void VisitLoadAndTest(InstructionSelector* selector, InstructionCode opcode,
opcode = cont->Encode(opcode); opcode = cont->Encode(opcode);
if (cont->IsDeoptimize()) { if (cont->IsDeoptimize()) {
selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs,
cont->kind(), cont->reason(), cont->frame_state()); cont->kind(), cont->reason(), cont->feedback(),
cont->frame_state());
} else { } else {
selector->Emit(opcode, output_count, outputs, input_count, inputs); selector->Emit(opcode, output_count, outputs, input_count, inputs);
} }
...@@ -2136,14 +2141,14 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, ...@@ -2136,14 +2141,14 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
void InstructionSelector::VisitDeoptimizeIf(Node* node) { void InstructionSelector::VisitDeoptimizeIf(Node* node) {
DeoptimizeParameters p = DeoptimizeParametersOf(node->op()); DeoptimizeParameters p = DeoptimizeParametersOf(node->op());
FlagsContinuation cont = FlagsContinuation::ForDeoptimize( FlagsContinuation cont = FlagsContinuation::ForDeoptimize(
kNotEqual, p.kind(), p.reason(), node->InputAt(1)); kNotEqual, p.kind(), p.reason(), p.feedback(), node->InputAt(1));
VisitWord32CompareZero(this, node, node->InputAt(0), &cont); VisitWord32CompareZero(this, node, node->InputAt(0), &cont);
} }
void InstructionSelector::VisitDeoptimizeUnless(Node* node) { void InstructionSelector::VisitDeoptimizeUnless(Node* node) {
DeoptimizeParameters p = DeoptimizeParametersOf(node->op()); DeoptimizeParameters p = DeoptimizeParametersOf(node->op());
FlagsContinuation cont = FlagsContinuation::ForDeoptimize( FlagsContinuation cont = FlagsContinuation::ForDeoptimize(
kEqual, p.kind(), p.reason(), node->InputAt(1)); kEqual, p.kind(), p.reason(), p.feedback(), node->InputAt(1));
VisitWord32CompareZero(this, node, node->InputAt(0), &cont); VisitWord32CompareZero(this, node, node->InputAt(0), &cont);
} }
......
...@@ -521,7 +521,8 @@ static void VisitBinop(InstructionSelector* selector, Node* node, ...@@ -521,7 +521,8 @@ static void VisitBinop(InstructionSelector* selector, Node* node,
opcode = cont->Encode(opcode); opcode = cont->Encode(opcode);
if (cont->IsDeoptimize()) { if (cont->IsDeoptimize()) {
selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs,
cont->kind(), cont->reason(), cont->frame_state()); cont->kind(), cont->reason(), cont->feedback(),
cont->frame_state());
} else { } else {
selector->Emit(opcode, output_count, outputs, input_count, inputs); selector->Emit(opcode, output_count, outputs, input_count, inputs);
} }
...@@ -1571,7 +1572,8 @@ void VisitCompareWithMemoryOperand(InstructionSelector* selector, ...@@ -1571,7 +1572,8 @@ void VisitCompareWithMemoryOperand(InstructionSelector* selector,
selector->Emit(opcode, 0, nullptr, input_count, inputs); selector->Emit(opcode, 0, nullptr, input_count, inputs);
} else if (cont->IsDeoptimize()) { } else if (cont->IsDeoptimize()) {
selector->EmitDeoptimize(opcode, 0, nullptr, input_count, inputs, selector->EmitDeoptimize(opcode, 0, nullptr, input_count, inputs,
cont->kind(), cont->reason(), cont->frame_state()); cont->kind(), cont->reason(), cont->feedback(),
cont->frame_state());
} else if (cont->IsSet()) { } else if (cont->IsSet()) {
InstructionOperand output = g.DefineAsRegister(cont->result()); InstructionOperand output = g.DefineAsRegister(cont->result());
selector->Emit(opcode, 1, &output, input_count, inputs); selector->Emit(opcode, 1, &output, input_count, inputs);
...@@ -1593,7 +1595,8 @@ void VisitCompare(InstructionSelector* selector, InstructionCode opcode, ...@@ -1593,7 +1595,8 @@ void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
g.Label(cont->true_block()), g.Label(cont->false_block())); g.Label(cont->true_block()), g.Label(cont->false_block()));
} else if (cont->IsDeoptimize()) { } else if (cont->IsDeoptimize()) {
selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, cont->kind(), selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, cont->kind(),
cont->reason(), cont->frame_state()); cont->reason(), cont->feedback(),
cont->frame_state());
} else if (cont->IsSet()) { } else if (cont->IsSet()) {
selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right);
} else { } else {
...@@ -1781,7 +1784,8 @@ void VisitWord64Compare(InstructionSelector* selector, Node* node, ...@@ -1781,7 +1784,8 @@ void VisitWord64Compare(InstructionSelector* selector, Node* node,
g.Label(cont->false_block())); g.Label(cont->false_block()));
} else if (cont->IsDeoptimize()) { } else if (cont->IsDeoptimize()) {
selector->EmitDeoptimize(opcode, 0, nullptr, 0, nullptr, cont->kind(), selector->EmitDeoptimize(opcode, 0, nullptr, 0, nullptr, cont->kind(),
cont->reason(), cont->frame_state()); cont->reason(), cont->feedback(),
cont->frame_state());
} else if (cont->IsSet()) { } else if (cont->IsSet()) {
selector->Emit(opcode, g.DefineAsRegister(cont->result())); selector->Emit(opcode, g.DefineAsRegister(cont->result()));
} else { } else {
...@@ -1981,14 +1985,14 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, ...@@ -1981,14 +1985,14 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
void InstructionSelector::VisitDeoptimizeIf(Node* node) { void InstructionSelector::VisitDeoptimizeIf(Node* node) {
DeoptimizeParameters p = DeoptimizeParametersOf(node->op()); DeoptimizeParameters p = DeoptimizeParametersOf(node->op());
FlagsContinuation cont = FlagsContinuation::ForDeoptimize( FlagsContinuation cont = FlagsContinuation::ForDeoptimize(
kNotEqual, p.kind(), p.reason(), node->InputAt(1)); kNotEqual, p.kind(), p.reason(), p.feedback(), node->InputAt(1));
VisitWordCompareZero(this, node, node->InputAt(0), &cont); VisitWordCompareZero(this, node, node->InputAt(0), &cont);
} }
void InstructionSelector::VisitDeoptimizeUnless(Node* node) { void InstructionSelector::VisitDeoptimizeUnless(Node* node) {
DeoptimizeParameters p = DeoptimizeParametersOf(node->op()); DeoptimizeParameters p = DeoptimizeParametersOf(node->op());
FlagsContinuation cont = FlagsContinuation::ForDeoptimize( FlagsContinuation cont = FlagsContinuation::ForDeoptimize(
kEqual, p.kind(), p.reason(), node->InputAt(1)); kEqual, p.kind(), p.reason(), p.feedback(), node->InputAt(1));
VisitWordCompareZero(this, node, node->InputAt(0), &cont); VisitWordCompareZero(this, node, node->InputAt(0), &cont);
} }
......
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