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