Commit 5c8ac0f3 authored by Sigurd Schneider's avatar Sigurd Schneider Committed by Commit Bot

[turbofan] Add feedback to CheckMaps and Deoptimize nodes

Bug: v8:7127
Change-Id: I79be6acaa04623fe9a5d314de5cb10811724db5f
Reviewed-on: https://chromium-review.googlesource.com/814401
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49996}
parent 4b949591
...@@ -103,8 +103,9 @@ Reduction BranchElimination::ReduceDeoptimizeConditional(Node* node) { ...@@ -103,8 +103,9 @@ Reduction BranchElimination::ReduceDeoptimizeConditional(Node* node) {
// with the {control} node that already contains the right information. // with the {control} node that already contains the right information.
ReplaceWithValue(node, dead(), effect, control); ReplaceWithValue(node, dead(), effect, control);
} else { } else {
control = graph()->NewNode(common()->Deoptimize(p.kind(), p.reason()), control = graph()->NewNode(
frame_state, effect, control); common()->Deoptimize(p.kind(), p.reason(), VectorSlotPair()),
frame_state, effect, control);
// TODO(bmeurer): This should be on the AdvancedReducer somehow. // TODO(bmeurer): This should be on the AdvancedReducer somehow.
NodeProperties::MergeControlToEnd(graph(), common(), control); NodeProperties::MergeControlToEnd(graph(), common(), control);
Revisit(graph()->end()); Revisit(graph()->end());
......
...@@ -138,9 +138,10 @@ Reduction CommonOperatorReducer::ReduceDeoptimizeConditional(Node* node) { ...@@ -138,9 +138,10 @@ Reduction CommonOperatorReducer::ReduceDeoptimizeConditional(Node* node) {
if (condition->opcode() == IrOpcode::kBooleanNot) { if (condition->opcode() == IrOpcode::kBooleanNot) {
NodeProperties::ReplaceValueInput(node, condition->InputAt(0), 0); NodeProperties::ReplaceValueInput(node, condition->InputAt(0), 0);
NodeProperties::ChangeOp( NodeProperties::ChangeOp(
node, condition_is_true node, condition_is_true ? common()->DeoptimizeIf(p.kind(), p.reason(),
? common()->DeoptimizeIf(p.kind(), p.reason()) VectorSlotPair())
: common()->DeoptimizeUnless(p.kind(), p.reason())); : common()->DeoptimizeUnless(
p.kind(), p.reason(), VectorSlotPair()));
return Changed(node); return Changed(node);
} }
Decision const decision = DecideCondition(condition); Decision const decision = DecideCondition(condition);
...@@ -148,8 +149,9 @@ Reduction CommonOperatorReducer::ReduceDeoptimizeConditional(Node* node) { ...@@ -148,8 +149,9 @@ Reduction CommonOperatorReducer::ReduceDeoptimizeConditional(Node* node) {
if (condition_is_true == (decision == Decision::kTrue)) { if (condition_is_true == (decision == Decision::kTrue)) {
ReplaceWithValue(node, dead(), effect, control); ReplaceWithValue(node, dead(), effect, control);
} else { } else {
control = graph()->NewNode(common()->Deoptimize(p.kind(), p.reason()), control = graph()->NewNode(
frame_state, effect, control); common()->Deoptimize(p.kind(), p.reason(), VectorSlotPair()),
frame_state, effect, control);
// TODO(bmeurer): This should be on the AdvancedReducer somehow. // TODO(bmeurer): This should be on the AdvancedReducer somehow.
NodeProperties::MergeControlToEnd(graph(), common(), control); NodeProperties::MergeControlToEnd(graph(), common(), control);
Revisit(graph()->end()); Revisit(graph()->end());
......
...@@ -43,7 +43,8 @@ int ValueInputCountOfReturn(Operator const* const op) { ...@@ -43,7 +43,8 @@ int ValueInputCountOfReturn(Operator const* const op) {
} }
bool operator==(DeoptimizeParameters lhs, DeoptimizeParameters rhs) { bool operator==(DeoptimizeParameters lhs, DeoptimizeParameters rhs) {
return lhs.kind() == rhs.kind() && lhs.reason() == rhs.reason(); return lhs.kind() == rhs.kind() && lhs.reason() == rhs.reason() &&
lhs.feedback() == rhs.feedback();
} }
bool operator!=(DeoptimizeParameters lhs, DeoptimizeParameters rhs) { bool operator!=(DeoptimizeParameters lhs, DeoptimizeParameters rhs) {
...@@ -51,11 +52,15 @@ bool operator!=(DeoptimizeParameters lhs, DeoptimizeParameters rhs) { ...@@ -51,11 +52,15 @@ bool operator!=(DeoptimizeParameters lhs, DeoptimizeParameters rhs) {
} }
size_t hash_value(DeoptimizeParameters p) { size_t hash_value(DeoptimizeParameters p) {
return base::hash_combine(p.kind(), p.reason()); return base::hash_combine(p.kind(), p.reason(), p.feedback());
} }
std::ostream& operator<<(std::ostream& os, DeoptimizeParameters p) { std::ostream& operator<<(std::ostream& os, DeoptimizeParameters p) {
return os << p.kind() << ":" << p.reason(); os << p.kind() << ":" << p.reason();
if (p.feedback().IsValid()) {
os << "; " << p.feedback();
}
return os;
} }
DeoptimizeParameters const& DeoptimizeParametersOf(Operator const* const op) { DeoptimizeParameters const& DeoptimizeParametersOf(Operator const* const op) {
...@@ -606,7 +611,7 @@ struct CommonOperatorGlobalCache final { ...@@ -606,7 +611,7 @@ struct CommonOperatorGlobalCache final {
Operator::kFoldable | Operator::kNoThrow, // properties Operator::kFoldable | Operator::kNoThrow, // properties
"Deoptimize", // name "Deoptimize", // name
1, 1, 1, 0, 0, 1, // counts 1, 1, 1, 0, 0, 1, // counts
DeoptimizeParameters(kKind, kReason)) {} // parameter DeoptimizeParameters(kKind, kReason, VectorSlotPair())) {}
}; };
#define CACHED_DEOPTIMIZE(Kind, Reason) \ #define CACHED_DEOPTIMIZE(Kind, Reason) \
DeoptimizeOperator<DeoptimizeKind::k##Kind, DeoptimizeReason::k##Reason> \ DeoptimizeOperator<DeoptimizeKind::k##Kind, DeoptimizeReason::k##Reason> \
...@@ -622,7 +627,7 @@ struct CommonOperatorGlobalCache final { ...@@ -622,7 +627,7 @@ struct CommonOperatorGlobalCache final {
Operator::kFoldable | Operator::kNoThrow, // properties Operator::kFoldable | Operator::kNoThrow, // properties
"DeoptimizeIf", // name "DeoptimizeIf", // name
2, 1, 1, 0, 1, 1, // counts 2, 1, 1, 0, 1, 1, // counts
DeoptimizeParameters(kKind, kReason)) {} // parameter DeoptimizeParameters(kKind, kReason, VectorSlotPair())) {}
}; };
#define CACHED_DEOPTIMIZE_IF(Kind, Reason) \ #define CACHED_DEOPTIMIZE_IF(Kind, Reason) \
DeoptimizeIfOperator<DeoptimizeKind::k##Kind, DeoptimizeReason::k##Reason> \ DeoptimizeIfOperator<DeoptimizeKind::k##Kind, DeoptimizeReason::k##Reason> \
...@@ -639,7 +644,7 @@ struct CommonOperatorGlobalCache final { ...@@ -639,7 +644,7 @@ struct CommonOperatorGlobalCache final {
Operator::kFoldable | Operator::kNoThrow, // properties Operator::kFoldable | Operator::kNoThrow, // properties
"DeoptimizeUnless", // name "DeoptimizeUnless", // name
2, 1, 1, 0, 1, 1, // counts 2, 1, 1, 0, 1, 1, // counts
DeoptimizeParameters(kKind, kReason)) {} // parameter DeoptimizeParameters(kKind, kReason, VectorSlotPair())) {}
}; };
#define CACHED_DEOPTIMIZE_UNLESS(Kind, Reason) \ #define CACHED_DEOPTIMIZE_UNLESS(Kind, Reason) \
DeoptimizeUnlessOperator<DeoptimizeKind::k##Kind, \ DeoptimizeUnlessOperator<DeoptimizeKind::k##Kind, \
...@@ -817,8 +822,9 @@ const Operator* CommonOperatorBuilder::Branch(BranchHint hint) { ...@@ -817,8 +822,9 @@ const Operator* CommonOperatorBuilder::Branch(BranchHint hint) {
UNREACHABLE(); UNREACHABLE();
} }
const Operator* CommonOperatorBuilder::Deoptimize(DeoptimizeKind kind, const Operator* CommonOperatorBuilder::Deoptimize(
DeoptimizeReason reason) { DeoptimizeKind kind, DeoptimizeReason reason,
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) { \
...@@ -827,7 +833,7 @@ const Operator* CommonOperatorBuilder::Deoptimize(DeoptimizeKind kind, ...@@ -827,7 +833,7 @@ const Operator* CommonOperatorBuilder::Deoptimize(DeoptimizeKind kind,
CACHED_DEOPTIMIZE_LIST(CACHED_DEOPTIMIZE) CACHED_DEOPTIMIZE_LIST(CACHED_DEOPTIMIZE)
#undef CACHED_DEOPTIMIZE #undef CACHED_DEOPTIMIZE
// Uncached // Uncached
DeoptimizeParameters parameter(kind, reason); DeoptimizeParameters parameter(kind, reason, feedback);
return new (zone()) Operator1<DeoptimizeParameters>( // -- return new (zone()) Operator1<DeoptimizeParameters>( // --
IrOpcode::kDeoptimize, // opcodes IrOpcode::kDeoptimize, // opcodes
Operator::kFoldable | Operator::kNoThrow, // properties Operator::kFoldable | Operator::kNoThrow, // properties
...@@ -836,8 +842,9 @@ const Operator* CommonOperatorBuilder::Deoptimize(DeoptimizeKind kind, ...@@ -836,8 +842,9 @@ const Operator* CommonOperatorBuilder::Deoptimize(DeoptimizeKind kind,
parameter); // parameter parameter); // parameter
} }
const Operator* CommonOperatorBuilder::DeoptimizeIf(DeoptimizeKind kind, const Operator* CommonOperatorBuilder::DeoptimizeIf(
DeoptimizeReason reason) { DeoptimizeKind kind, DeoptimizeReason reason,
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) { \
...@@ -846,7 +853,7 @@ const Operator* CommonOperatorBuilder::DeoptimizeIf(DeoptimizeKind kind, ...@@ -846,7 +853,7 @@ const Operator* CommonOperatorBuilder::DeoptimizeIf(DeoptimizeKind kind,
CACHED_DEOPTIMIZE_IF_LIST(CACHED_DEOPTIMIZE_IF) CACHED_DEOPTIMIZE_IF_LIST(CACHED_DEOPTIMIZE_IF)
#undef CACHED_DEOPTIMIZE_IF #undef CACHED_DEOPTIMIZE_IF
// Uncached // Uncached
DeoptimizeParameters parameter(kind, reason); DeoptimizeParameters parameter(kind, reason, feedback);
return new (zone()) Operator1<DeoptimizeParameters>( // -- return new (zone()) Operator1<DeoptimizeParameters>( // --
IrOpcode::kDeoptimizeIf, // opcode IrOpcode::kDeoptimizeIf, // opcode
Operator::kFoldable | Operator::kNoThrow, // properties Operator::kFoldable | Operator::kNoThrow, // properties
...@@ -856,7 +863,8 @@ const Operator* CommonOperatorBuilder::DeoptimizeIf(DeoptimizeKind kind, ...@@ -856,7 +863,8 @@ const Operator* CommonOperatorBuilder::DeoptimizeIf(DeoptimizeKind kind,
} }
const Operator* CommonOperatorBuilder::DeoptimizeUnless( const Operator* CommonOperatorBuilder::DeoptimizeUnless(
DeoptimizeKind kind, DeoptimizeReason reason) { DeoptimizeKind kind, DeoptimizeReason reason,
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) { \
...@@ -865,7 +873,7 @@ const Operator* CommonOperatorBuilder::DeoptimizeUnless( ...@@ -865,7 +873,7 @@ const Operator* CommonOperatorBuilder::DeoptimizeUnless(
CACHED_DEOPTIMIZE_UNLESS_LIST(CACHED_DEOPTIMIZE_UNLESS) CACHED_DEOPTIMIZE_UNLESS_LIST(CACHED_DEOPTIMIZE_UNLESS)
#undef CACHED_DEOPTIMIZE_UNLESS #undef CACHED_DEOPTIMIZE_UNLESS
// Uncached // Uncached
DeoptimizeParameters parameter(kind, reason); DeoptimizeParameters parameter(kind, reason, feedback);
return new (zone()) Operator1<DeoptimizeParameters>( // -- return new (zone()) Operator1<DeoptimizeParameters>( // --
IrOpcode::kDeoptimizeUnless, // opcode IrOpcode::kDeoptimizeUnless, // opcode
Operator::kFoldable | Operator::kNoThrow, // properties Operator::kFoldable | Operator::kNoThrow, // properties
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "src/deoptimize-reason.h" #include "src/deoptimize-reason.h"
#include "src/globals.h" #include "src/globals.h"
#include "src/machine-type.h" #include "src/machine-type.h"
#include "src/vector-slot-pair.h"
#include "src/zone/zone-containers.h" #include "src/zone/zone-containers.h"
#include "src/zone/zone-handle-set.h" #include "src/zone/zone-handle-set.h"
...@@ -52,15 +53,18 @@ int ValueInputCountOfReturn(Operator const* const op); ...@@ -52,15 +53,18 @@ int ValueInputCountOfReturn(Operator const* const op);
// Parameters for the {Deoptimize} operator. // Parameters for the {Deoptimize} operator.
class DeoptimizeParameters final { class DeoptimizeParameters final {
public: public:
DeoptimizeParameters(DeoptimizeKind kind, DeoptimizeReason reason) DeoptimizeParameters(DeoptimizeKind kind, DeoptimizeReason reason,
: kind_(kind), reason_(reason) {} VectorSlotPair const& feedback)
: kind_(kind), reason_(reason), feedback_(feedback) {}
DeoptimizeKind kind() const { return kind_; } DeoptimizeKind kind() const { return kind_; }
DeoptimizeReason reason() const { return reason_; } DeoptimizeReason reason() const { return reason_; }
const VectorSlotPair& feedback() const { return feedback_; }
private: private:
DeoptimizeKind const kind_; DeoptimizeKind const kind_;
DeoptimizeReason const reason_; DeoptimizeReason const reason_;
VectorSlotPair const feedback_;
}; };
bool operator==(DeoptimizeParameters, DeoptimizeParameters); bool operator==(DeoptimizeParameters, DeoptimizeParameters);
...@@ -358,10 +362,12 @@ class V8_EXPORT_PRIVATE CommonOperatorBuilder final ...@@ -358,10 +362,12 @@ class V8_EXPORT_PRIVATE CommonOperatorBuilder final
const Operator* IfValue(int32_t value); const Operator* IfValue(int32_t value);
const Operator* IfDefault(); const Operator* IfDefault();
const Operator* Throw(); const Operator* Throw();
const Operator* Deoptimize(DeoptimizeKind kind, DeoptimizeReason reason); const Operator* Deoptimize(DeoptimizeKind kind, DeoptimizeReason reason,
const Operator* DeoptimizeIf(DeoptimizeKind kind, DeoptimizeReason reason); VectorSlotPair const& feedback);
const Operator* DeoptimizeUnless(DeoptimizeKind kind, const Operator* DeoptimizeIf(DeoptimizeKind kind, DeoptimizeReason reason,
DeoptimizeReason reason); VectorSlotPair const& feedback);
const Operator* DeoptimizeUnless(DeoptimizeKind kind, DeoptimizeReason reason,
VectorSlotPair const& feedback);
const Operator* TrapIf(int32_t trap_id); const Operator* TrapIf(int32_t trap_id);
const Operator* TrapUnless(int32_t trap_id); const Operator* TrapUnless(int32_t trap_id);
const Operator* Return(int value_input_count = 1); const Operator* Return(int value_input_count = 1);
......
...@@ -1355,7 +1355,7 @@ void EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state) { ...@@ -1355,7 +1355,7 @@ void EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state) {
__ Int32Constant(Map::IsDeprecatedBit::kMask)), __ Int32Constant(Map::IsDeprecatedBit::kMask)),
__ Int32Constant(0)); __ Int32Constant(0));
__ DeoptimizeIf(DeoptimizeReason::kWrongMap, if_not_deprecated, __ DeoptimizeIf(DeoptimizeReason::kWrongMap, if_not_deprecated,
frame_state); frame_state, p.feedback());
Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow; Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow;
Runtime::FunctionId id = Runtime::kTryMigrateInstance; Runtime::FunctionId id = Runtime::kTryMigrateInstance;
...@@ -1367,7 +1367,7 @@ void EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state) { ...@@ -1367,7 +1367,7 @@ void EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state) {
__ Int32Constant(1), __ NoContextConstant()); __ Int32Constant(1), __ NoContextConstant());
Node* check = ObjectIsSmi(result); Node* check = ObjectIsSmi(result);
__ DeoptimizeIf(DeoptimizeReason::kInstanceMigrationFailed, check, __ DeoptimizeIf(DeoptimizeReason::kInstanceMigrationFailed, check,
frame_state); frame_state, p.feedback());
} }
// Reload the current map of the {value}. // Reload the current map of the {value}.
...@@ -1378,7 +1378,8 @@ void EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state) { ...@@ -1378,7 +1378,8 @@ void EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state) {
Node* map = __ HeapConstant(maps[i]); Node* map = __ HeapConstant(maps[i]);
Node* check = __ WordEqual(value_map, map); Node* check = __ WordEqual(value_map, map);
if (i == map_count - 1) { if (i == map_count - 1) {
__ DeoptimizeIfNot(DeoptimizeReason::kWrongMap, check, frame_state); __ DeoptimizeIfNot(DeoptimizeReason::kWrongMap, check, frame_state,
p.feedback());
} else { } else {
__ GotoIf(check, &done); __ GotoIf(check, &done);
} }
...@@ -1396,7 +1397,8 @@ void EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state) { ...@@ -1396,7 +1397,8 @@ void EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state) {
Node* map = __ HeapConstant(maps[i]); Node* map = __ HeapConstant(maps[i]);
Node* check = __ WordEqual(value_map, map); Node* check = __ WordEqual(value_map, map);
if (i == map_count - 1) { if (i == map_count - 1) {
__ DeoptimizeIfNot(DeoptimizeReason::kWrongMap, check, frame_state); __ DeoptimizeIfNot(DeoptimizeReason::kWrongMap, check, frame_state,
p.feedback());
} else { } else {
__ GotoIf(check, &done); __ GotoIf(check, &done);
} }
...@@ -1524,7 +1526,7 @@ Node* EffectControlLinearizer::LowerCheckInternalizedString(Node* node, ...@@ -1524,7 +1526,7 @@ Node* EffectControlLinearizer::LowerCheckInternalizedString(Node* node,
void EffectControlLinearizer::LowerCheckIf(Node* node, Node* frame_state) { void EffectControlLinearizer::LowerCheckIf(Node* node, Node* frame_state) {
Node* value = node->InputAt(0); Node* value = node->InputAt(0);
__ DeoptimizeIfNot(DeoptimizeKind::kEager, DeoptimizeReasonOf(node->op()), __ DeoptimizeIfNot(DeoptimizeKind::kEager, DeoptimizeReasonOf(node->op()),
value, frame_state); value, frame_state, VectorSlotPair());
} }
Node* EffectControlLinearizer::LowerCheckedInt32Add(Node* node, Node* EffectControlLinearizer::LowerCheckedInt32Add(Node* node,
......
...@@ -165,24 +165,27 @@ Node* GraphAssembler::ToNumber(Node* value) { ...@@ -165,24 +165,27 @@ Node* GraphAssembler::ToNumber(Node* value) {
} }
Node* GraphAssembler::DeoptimizeIf(DeoptimizeReason reason, Node* condition, Node* GraphAssembler::DeoptimizeIf(DeoptimizeReason reason, Node* condition,
Node* frame_state) { Node* frame_state,
VectorSlotPair const& feedback) {
return current_control_ = current_effect_ = graph()->NewNode( return current_control_ = current_effect_ = graph()->NewNode(
common()->DeoptimizeIf(DeoptimizeKind::kEager, reason), condition, common()->DeoptimizeIf(DeoptimizeKind::kEager, reason, feedback),
frame_state, current_effect_, current_control_); condition, frame_state, current_effect_, current_control_);
} }
Node* GraphAssembler::DeoptimizeIfNot(DeoptimizeKind kind, Node* GraphAssembler::DeoptimizeIfNot(DeoptimizeKind kind,
DeoptimizeReason reason, Node* condition, DeoptimizeReason reason, Node* condition,
Node* frame_state) { Node* frame_state,
VectorSlotPair const& feedback) {
return current_control_ = current_effect_ = graph()->NewNode( return current_control_ = current_effect_ = graph()->NewNode(
common()->DeoptimizeUnless(kind, reason), condition, frame_state, common()->DeoptimizeUnless(kind, reason, feedback), condition,
current_effect_, current_control_); frame_state, current_effect_, current_control_);
} }
Node* GraphAssembler::DeoptimizeIfNot(DeoptimizeReason reason, Node* condition, Node* GraphAssembler::DeoptimizeIfNot(DeoptimizeReason reason, Node* condition,
Node* frame_state) { Node* frame_state,
return DeoptimizeIfNot(DeoptimizeKind::kEager, reason, condition, VectorSlotPair const& feedback) {
frame_state); return DeoptimizeIfNot(DeoptimizeKind::kEager, reason, condition, frame_state,
feedback);
} }
void GraphAssembler::Branch(Node* condition, GraphAssemblerLabel<0u>* if_true, void GraphAssembler::Branch(Node* condition, GraphAssemblerLabel<0u>* if_true,
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "src/compiler/js-graph.h" #include "src/compiler/js-graph.h"
#include "src/compiler/node.h" #include "src/compiler/node.h"
#include "src/compiler/simplified-operator.h" #include "src/compiler/simplified-operator.h"
#include "src/vector-slot-pair.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -209,11 +210,14 @@ class GraphAssembler { ...@@ -209,11 +210,14 @@ class GraphAssembler {
Node* UnsafePointerAdd(Node* base, Node* external); Node* UnsafePointerAdd(Node* base, Node* external);
Node* DeoptimizeIf(DeoptimizeReason reason, Node* condition, Node* DeoptimizeIf(DeoptimizeReason reason, Node* condition,
Node* frame_state); Node* frame_state,
VectorSlotPair const& feedback = VectorSlotPair());
Node* DeoptimizeIfNot(DeoptimizeKind kind, DeoptimizeReason reason, Node* DeoptimizeIfNot(DeoptimizeKind kind, DeoptimizeReason reason,
Node* condition, Node* frame_state); Node* condition, Node* frame_state,
VectorSlotPair const& feedback);
Node* DeoptimizeIfNot(DeoptimizeReason reason, Node* condition, Node* DeoptimizeIfNot(DeoptimizeReason reason, Node* condition,
Node* frame_state); Node* frame_state,
VectorSlotPair const& feedback = VectorSlotPair());
template <typename... Args> template <typename... Args>
Node* Call(const CallDescriptor* desc, Args... args); Node* Call(const CallDescriptor* desc, Args... args);
template <typename... Args> template <typename... Args>
......
...@@ -2485,9 +2485,9 @@ Reduction JSCallReducer::ReduceSoftDeoptimize(Node* node, ...@@ -2485,9 +2485,9 @@ Reduction JSCallReducer::ReduceSoftDeoptimize(Node* node,
Node* effect = NodeProperties::GetEffectInput(node); Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node); Node* control = NodeProperties::GetControlInput(node);
Node* frame_state = NodeProperties::FindFrameStateBefore(node); Node* frame_state = NodeProperties::FindFrameStateBefore(node);
Node* deoptimize = Node* deoptimize = graph()->NewNode(
graph()->NewNode(common()->Deoptimize(DeoptimizeKind::kSoft, reason), common()->Deoptimize(DeoptimizeKind::kSoft, reason, VectorSlotPair()),
frame_state, effect, control); frame_state, effect, control);
// TODO(bmeurer): This should be on the AdvancedReducer somehow. // TODO(bmeurer): This should be on the AdvancedReducer somehow.
NodeProperties::MergeControlToEnd(graph(), common(), deoptimize); NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
Revisit(graph()->end()); Revisit(graph()->end());
......
...@@ -135,7 +135,8 @@ Reduction JSIntrinsicLowering::ReduceDeoptimizeNow(Node* node) { ...@@ -135,7 +135,8 @@ Reduction JSIntrinsicLowering::ReduceDeoptimizeNow(Node* node) {
// TODO(bmeurer): Move MergeControlToEnd() to the AdvancedReducer. // TODO(bmeurer): Move MergeControlToEnd() to the AdvancedReducer.
Node* deoptimize = graph()->NewNode( Node* deoptimize = graph()->NewNode(
common()->Deoptimize(DeoptimizeKind::kEager, DeoptimizeReason::kNoReason), common()->Deoptimize(DeoptimizeKind::kEager, DeoptimizeReason::kNoReason,
VectorSlotPair()),
frame_state, effect, control); frame_state, effect, control);
NodeProperties::MergeControlToEnd(graph(), common(), deoptimize); NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
Revisit(graph()->end()); Revisit(graph()->end());
......
...@@ -1424,9 +1424,9 @@ Reduction JSNativeContextSpecialization::ReduceSoftDeoptimize( ...@@ -1424,9 +1424,9 @@ Reduction JSNativeContextSpecialization::ReduceSoftDeoptimize(
Node* effect = NodeProperties::GetEffectInput(node); Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node); Node* control = NodeProperties::GetControlInput(node);
Node* frame_state = NodeProperties::FindFrameStateBefore(node); Node* frame_state = NodeProperties::FindFrameStateBefore(node);
Node* deoptimize = Node* deoptimize = graph()->NewNode(
graph()->NewNode(common()->Deoptimize(DeoptimizeKind::kSoft, reason), common()->Deoptimize(DeoptimizeKind::kSoft, reason, VectorSlotPair()),
frame_state, effect, control); frame_state, effect, control);
// TODO(bmeurer): This should be on the AdvancedReducer somehow. // TODO(bmeurer): This should be on the AdvancedReducer somehow.
NodeProperties::MergeControlToEnd(graph(), common(), deoptimize); NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
Revisit(graph()->end()); Revisit(graph()->end());
......
...@@ -493,7 +493,8 @@ Node* JSTypeHintLowering::TryBuildSoftDeopt(FeedbackNexus& nexus, Node* effect, ...@@ -493,7 +493,8 @@ Node* JSTypeHintLowering::TryBuildSoftDeopt(FeedbackNexus& nexus, Node* effect,
DeoptimizeReason reason) const { DeoptimizeReason reason) const {
if ((flags() & kBailoutOnUninitialized) && nexus.IsUninitialized()) { if ((flags() & kBailoutOnUninitialized) && nexus.IsUninitialized()) {
Node* deoptimize = jsgraph()->graph()->NewNode( Node* deoptimize = jsgraph()->graph()->NewNode(
jsgraph()->common()->Deoptimize(DeoptimizeKind::kSoft, reason), jsgraph()->common()->Deoptimize(DeoptimizeKind::kSoft, reason,
VectorSlotPair()),
jsgraph()->Dead(), effect, control); jsgraph()->Dead(), effect, control);
Node* frame_state = NodeProperties::FindFrameStateBefore(deoptimize); Node* frame_state = NodeProperties::FindFrameStateBefore(deoptimize);
deoptimize->ReplaceInput(0, frame_state); deoptimize->ReplaceInput(0, frame_state);
......
...@@ -215,15 +215,20 @@ size_t hash_value(MapsParameterInfo const& p) { return hash_value(p.maps()); } ...@@ -215,15 +215,20 @@ size_t hash_value(MapsParameterInfo const& p) { return hash_value(p.maps()); }
bool operator==(CheckMapsParameters const& lhs, bool operator==(CheckMapsParameters const& lhs,
CheckMapsParameters const& rhs) { CheckMapsParameters const& rhs) {
return lhs.flags() == rhs.flags() && lhs.maps() == rhs.maps(); return lhs.flags() == rhs.flags() && lhs.maps() == rhs.maps() &&
lhs.feedback() == rhs.feedback();
} }
size_t hash_value(CheckMapsParameters const& p) { size_t hash_value(CheckMapsParameters const& p) {
return base::hash_combine(p.flags(), p.maps()); return base::hash_combine(p.flags(), p.maps(), p.feedback());
} }
std::ostream& operator<<(std::ostream& os, CheckMapsParameters const& p) { std::ostream& operator<<(std::ostream& os, CheckMapsParameters const& p) {
return os << p.flags() << p.maps_info(); os << p.flags() << p.maps_info();
if (p.feedback().IsValid()) {
os << "; " << p.feedback();
}
return os;
} }
CheckMapsParameters const& CheckMapsParametersOf(Operator const* op) { CheckMapsParameters const& CheckMapsParametersOf(Operator const* op) {
...@@ -1021,9 +1026,10 @@ const Operator* SimplifiedOperatorBuilder::CheckedTruncateTaggedToWord32( ...@@ -1021,9 +1026,10 @@ const Operator* SimplifiedOperatorBuilder::CheckedTruncateTaggedToWord32(
UNREACHABLE(); UNREACHABLE();
} }
const Operator* SimplifiedOperatorBuilder::CheckMaps(CheckMapsFlags flags, const Operator* SimplifiedOperatorBuilder::CheckMaps(
ZoneHandleSet<Map> maps) { CheckMapsFlags flags, ZoneHandleSet<Map> maps,
CheckMapsParameters const parameters(flags, maps); const VectorSlotPair& feedback) {
CheckMapsParameters const parameters(flags, maps, feedback);
return new (zone()) Operator1<CheckMapsParameters>( // -- return new (zone()) Operator1<CheckMapsParameters>( // --
IrOpcode::kCheckMaps, // opcode IrOpcode::kCheckMaps, // opcode
Operator::kNoThrow | Operator::kNoWrite, // flags Operator::kNoThrow | Operator::kNoWrite, // flags
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "src/machine-type.h" #include "src/machine-type.h"
#include "src/objects.h" #include "src/objects.h"
#include "src/type-hints.h" #include "src/type-hints.h"
#include "src/vector-slot-pair.h"
#include "src/zone/zone-handle-set.h" #include "src/zone/zone-handle-set.h"
namespace v8 { namespace v8 {
...@@ -155,19 +156,24 @@ bool operator!=(MapsParameterInfo const&, MapsParameterInfo const&); ...@@ -155,19 +156,24 @@ bool operator!=(MapsParameterInfo const&, MapsParameterInfo const&);
size_t hash_value(MapsParameterInfo const&); size_t hash_value(MapsParameterInfo const&);
// A descriptor for map checks. // A descriptor for map checks. The {feedback} parameter is optional.
// If {feedback} references a valid CallIC slot and this MapCheck fails,
// then speculation on that CallIC slot will be disabled.
class CheckMapsParameters final { class CheckMapsParameters final {
public: public:
CheckMapsParameters(CheckMapsFlags flags, ZoneHandleSet<Map> const& maps) CheckMapsParameters(CheckMapsFlags flags, ZoneHandleSet<Map> const& maps,
: flags_(flags), maps_info_(maps) {} const VectorSlotPair& feedback)
: flags_(flags), maps_info_(maps), feedback_(feedback) {}
CheckMapsFlags flags() const { return flags_; } CheckMapsFlags flags() const { return flags_; }
ZoneHandleSet<Map> const& maps() const { return maps_info_.maps(); } ZoneHandleSet<Map> const& maps() const { return maps_info_.maps(); }
MapsParameterInfo const& maps_info() const { return maps_info_; } MapsParameterInfo const& maps_info() const { return maps_info_; }
VectorSlotPair const& feedback() const { return feedback_; }
private: private:
CheckMapsFlags const flags_; CheckMapsFlags const flags_;
MapsParameterInfo const maps_info_; MapsParameterInfo const maps_info_;
VectorSlotPair const feedback_;
}; };
bool operator==(CheckMapsParameters const&, CheckMapsParameters const&); bool operator==(CheckMapsParameters const&, CheckMapsParameters const&);
...@@ -438,7 +444,8 @@ class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final ...@@ -438,7 +444,8 @@ class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final
const Operator* CheckIf(DeoptimizeReason deoptimize_reason); const Operator* CheckIf(DeoptimizeReason deoptimize_reason);
const Operator* CheckBounds(); const Operator* CheckBounds();
const Operator* CheckMaps(CheckMapsFlags, ZoneHandleSet<Map>); const Operator* CheckMaps(CheckMapsFlags, ZoneHandleSet<Map>,
const VectorSlotPair& = VectorSlotPair());
const Operator* CompareMaps(ZoneHandleSet<Map>); const Operator* CompareMaps(ZoneHandleSet<Map>);
const Operator* MapGuard(ZoneHandleSet<Map> maps); const Operator* MapGuard(ZoneHandleSet<Map> maps);
......
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