Commit 779540c6 authored by Nico Hartmann's avatar Nico Hartmann Committed by Commit Bot

Move feedback for BigIntTooBig from deoptimizer to interpreter

Feedback shall not be updated by the deoptimizer. Although this
mechanism exists, it shall not be used if possible. This CL changes
how V8 learns from BigInt deopts: Previously we updated feedback on
the BinaryOperations in the deoptimizer, now we let the interpreter
widen the feedback type from BigInt to Any after the deopt has occurred.

Bug: v8:9407
Change-Id: I92e5e733085b433fd8ab452674d02404b81b2796
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1687419Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Reviewed-by: 's avatarSigurd Schneider <sigurds@chromium.org>
Commit-Queue: Nico Hartmann <nicohartmann@google.com>
Cr-Commit-Position: refs/heads/master@{#62548}
parent 7e0f961e
......@@ -4217,7 +4217,6 @@ Node* EffectControlLinearizer::LowerStringLessThanOrEqual(Node* node) {
Node* EffectControlLinearizer::LowerSpeculativeBigIntAdd(Node* node,
Node* frame_state) {
const auto& p = BigIntOperationParametersOf(node->op());
Node* lhs = node->InputAt(0);
Node* rhs = node->InputAt(1);
......@@ -4232,7 +4231,7 @@ Node* EffectControlLinearizer::LowerSpeculativeBigIntAdd(Node* node,
rhs, __ NoContextConstant());
// Check for exception sentinel: Smi is returned to signal BigIntTooBig.
__ DeoptimizeIf(DeoptimizeReason::kBigIntTooBig, p.feedback(),
__ DeoptimizeIf(DeoptimizeReason::kBigIntTooBig, VectorSlotPair{},
ObjectIsSmi(value), frame_state);
return value;
......
......@@ -162,11 +162,10 @@ class JSSpeculativeBinopBuilder final {
UNREACHABLE();
}
const Operator* SpeculativeBigIntOp(BigIntOperationHint hint,
const VectorSlotPair& feedback) {
const Operator* SpeculativeBigIntOp(BigIntOperationHint hint) {
switch (op_->opcode()) {
case IrOpcode::kJSAdd:
return simplified()->SpeculativeBigIntAdd(hint, feedback);
return simplified()->SpeculativeBigIntAdd(hint);
default:
break;
}
......@@ -217,9 +216,7 @@ class JSSpeculativeBinopBuilder final {
Node* TryBuildBigIntBinop() {
BigIntOperationHint hint;
if (GetBinaryBigIntOperationHint(&hint)) {
FeedbackNexus nexus{feedback_vector(), slot_};
VectorSlotPair feedback{feedback_vector(), slot_, nexus.ic_state()};
const Operator* op = SpeculativeBigIntOp(hint, feedback);
const Operator* op = SpeculativeBigIntOp(hint);
Node* node = BuildSpeculativeOperation(op);
return node;
}
......
......@@ -2642,8 +2642,8 @@ class RepresentationSelector {
return;
}
case IrOpcode::kSpeculativeBigIntAdd: {
const auto& p = BigIntOperationParametersOf(node->op());
VisitBinop(node, UseInfo::CheckedBigIntAsTaggedPointer(p.feedback()),
VisitBinop(node,
UseInfo::CheckedBigIntAsTaggedPointer(VectorSlotPair{}),
MachineRepresentation::kTaggedPointer);
return;
}
......
......@@ -504,25 +504,6 @@ size_t hash_value(BigIntOperationHint hint) {
return static_cast<uint8_t>(hint);
}
bool operator==(const BigIntOperationParameters& lhs,
const BigIntOperationParameters& rhs) {
return lhs.hint() == rhs.hint() && lhs.feedback() == rhs.feedback();
}
size_t hash_value(const BigIntOperationParameters& p) {
return base::hash_combine(p.hint(), p.feedback());
}
std::ostream& operator<<(std::ostream& os, const BigIntOperationParameters& p) {
return os << p.hint() << " " << p.feedback();
}
const BigIntOperationParameters& BigIntOperationParametersOf(
const Operator* op) {
DCHECK_EQ(IrOpcode::kSpeculativeBigIntAdd, op->opcode());
return OpParameter<BigIntOperationParameters>(op);
}
std::ostream& operator<<(std::ostream& os, NumberOperationHint hint) {
switch (hint) {
case NumberOperationHint::kSignedSmall:
......@@ -1446,11 +1427,10 @@ const Operator* SimplifiedOperatorBuilder::CheckFloat64Hole(
}
const Operator* SimplifiedOperatorBuilder::SpeculativeBigIntAdd(
BigIntOperationHint hint, const VectorSlotPair& feedback) {
return new (zone()) Operator1<BigIntOperationParameters>(
BigIntOperationHint hint) {
return new (zone()) Operator1<BigIntOperationHint>(
IrOpcode::kSpeculativeBigIntAdd, Operator::kFoldable | Operator::kNoThrow,
"SpeculativeBigIntAdd", 2, 1, 1, 1, 1, 0,
BigIntOperationParameters{hint, feedback});
"SpeculativeBigIntAdd", 2, 1, 1, 1, 1, 0, hint);
}
const Operator* SimplifiedOperatorBuilder::SpeculativeToNumber(
......
......@@ -487,28 +487,6 @@ V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, BigIntOperationHint);
V8_EXPORT_PRIVATE NumberOperationHint NumberOperationHintOf(const Operator* op)
V8_WARN_UNUSED_RESULT;
class BigIntOperationParameters {
public:
BigIntOperationParameters(BigIntOperationHint hint,
const VectorSlotPair& feedback)
: hint_(hint), feedback_(feedback) {}
BigIntOperationHint hint() const { return hint_; }
const VectorSlotPair& feedback() const { return feedback_; }
private:
BigIntOperationHint hint_;
VectorSlotPair feedback_;
};
size_t hash_value(const BigIntOperationParameters&);
V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&,
const BigIntOperationParameters&);
bool operator==(const BigIntOperationParameters& lhs,
const BigIntOperationParameters& rhs);
const BigIntOperationParameters& BigIntOperationParametersOf(const Operator* op)
V8_WARN_UNUSED_RESULT;
class NumberOperationParameters {
public:
NumberOperationParameters(NumberOperationHint hint,
......@@ -680,8 +658,7 @@ class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final
const Operator* SpeculativeNumberLessThanOrEqual(NumberOperationHint hint);
const Operator* SpeculativeNumberEqual(NumberOperationHint hint);
const Operator* SpeculativeBigIntAdd(BigIntOperationHint hint,
const VectorSlotPair& feedback);
const Operator* SpeculativeBigIntAdd(BigIntOperationHint hint);
const Operator* BigIntAsUintN(int bits);
const Operator* ReferenceEqual();
......
......@@ -4030,21 +4030,10 @@ void TranslatedState::VerifyMaterializedObjects() {
bool TranslatedState::DoUpdateFeedback() {
if (!feedback_vector_handle_.is_null()) {
CHECK(!feedback_slot_.IsInvalid());
isolate()->CountUsage(v8::Isolate::kDeoptimizerDisableSpeculation);
FeedbackNexus nexus(feedback_vector_handle_, feedback_slot_);
const auto kind = feedback_vector_handle_->GetKind(feedback_slot_);
if (kind == FeedbackSlotKind::kCall) {
isolate()->CountUsage(v8::Isolate::kDeoptimizerDisableSpeculation);
nexus.SetSpeculationMode(SpeculationMode::kDisallowSpeculation);
return true;
} else if (kind == FeedbackSlotKind::kBinaryOp) {
// To prevent a deopt loop for binary operations (like speculative
// addition of BigInts), we generalize feedback to Any.
return nexus.SetBinaryOpFeedbackToAny();
} else {
UNREACHABLE();
}
nexus.SetSpeculationMode(SpeculationMode::kDisallowSpeculation);
return true;
}
return false;
}
......
......@@ -176,15 +176,28 @@ Node* BinaryOpAssembler::Generate_AddWithFeedback(Node* context, Node* lhs,
Node* rhs_instance_type = LoadInstanceType(rhs);
Node* rhs_is_oddball = InstanceTypeEqual(rhs_instance_type, ODDBALL_TYPE);
GotoIf(rhs_is_oddball, &call_with_oddball_feedback);
Branch(IsBigIntInstanceType(rhs_instance_type), &bigint,
&call_with_any_feedback);
Goto(&call_with_any_feedback);
}
BIND(&bigint);
{
// Both {lhs} and {rhs} are of BigInt type.
Label bigint_too_big(this);
var_result.Bind(
CallBuiltin(Builtins::kBigIntAddNoThrow, context, lhs, rhs));
// Check for sentinel that signals BigIntTooBig exception.
GotoIf(TaggedIsSmi(var_result.value()), &bigint_too_big);
var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kBigInt));
var_result.Bind(CallBuiltin(Builtins::kBigIntAdd, context, lhs, rhs));
Goto(&end);
BIND(&bigint_too_big);
{
// Update feedback to prevent deopt loop.
UpdateFeedback(SmiConstant(BinaryOperationFeedback::kAny),
feedback_vector, slot_id);
ThrowRangeError(context, MessageTemplate::kBigIntTooBig);
}
}
BIND(&call_with_oddball_feedback);
......
......@@ -894,16 +894,6 @@ float FeedbackNexus::ComputeCallFrequency() {
return static_cast<float>(call_count / invocation_count);
}
bool FeedbackNexus::SetBinaryOpFeedbackToAny() {
DCHECK_EQ(kind(), FeedbackSlotKind::kBinaryOp);
int feedback = GetFeedback().ToSmi().value();
if (feedback == BinaryOperationFeedback::kAny) {
return false;
}
SetFeedback(Smi::FromInt(BinaryOperationFeedback::kAny));
return true;
}
void FeedbackNexus::ConfigureMonomorphic(Handle<Name> name,
Handle<Map> receiver_map,
const MaybeObjectHandle& handler) {
......
......@@ -673,7 +673,6 @@ class V8_EXPORT_PRIVATE FeedbackNexus final {
inline Isolate* GetIsolate() const;
bool SetBinaryOpFeedbackToAny();
void ConfigureMonomorphic(Handle<Name> name, Handle<Map> receiver_map,
const MaybeObjectHandle& handler);
......
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