Commit d9328fe6 authored by Georg Neis's avatar Georg Neis Committed by V8 LUCI CQ

Fix FeedbackNexus::SetSpeculationMode

This function broke abstraction and as a result became incorrect when
the call feedback was extended with the CallFeedbackContent flag.

Bug: v8:11821, v8:9974
Change-Id: Ic40dc45440a697a554d015dd50f0178e79963920
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2919820
Auto-Submit: Georg Neis <neis@chromium.org>
Commit-Queue: Michael Stanton <mvstanton@chromium.org>
Reviewed-by: 's avatarMichael Stanton <mvstanton@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74823}
parent 5fd38582
...@@ -992,11 +992,10 @@ void FeedbackNexus::SetSpeculationMode(SpeculationMode mode) { ...@@ -992,11 +992,10 @@ void FeedbackNexus::SetSpeculationMode(SpeculationMode mode) {
Object call_count = GetFeedbackExtra()->cast<Object>(); Object call_count = GetFeedbackExtra()->cast<Object>();
CHECK(call_count.IsSmi()); CHECK(call_count.IsSmi());
uint32_t count = static_cast<uint32_t>(Smi::ToInt(call_count)); uint32_t count = static_cast<uint32_t>(Smi::ToInt(call_count));
uint32_t value = CallCountField::encode(CallCountField::decode(count)); count = SpeculationModeField::update(count, mode);
int result = static_cast<int>(value | SpeculationModeField::encode(mode));
MaybeObject feedback = GetFeedback(); MaybeObject feedback = GetFeedback();
// We can skip the write barrier for {feedback} because it's not changing. // We can skip the write barrier for {feedback} because it's not changing.
SetFeedback(feedback, SKIP_WRITE_BARRIER, Smi::FromInt(result), SetFeedback(feedback, SKIP_WRITE_BARRIER, Smi::FromInt(count),
SKIP_WRITE_BARRIER); SKIP_WRITE_BARRIER);
} }
......
...@@ -427,6 +427,44 @@ TEST(VectorSpeculationMode) { ...@@ -427,6 +427,44 @@ TEST(VectorSpeculationMode) {
CHECK_EQ(3, nexus.GetCallCount()); CHECK_EQ(3, nexus.GetCallCount());
} }
TEST(VectorCallSpeculationModeAndFeedbackContent) {
if (!i::FLAG_use_ic) return;
if (!i::FLAG_opt) return;
if (i::FLAG_always_opt) return;
if (i::FLAG_jitless) return;
if (i::FLAG_turboprop) return;
FLAG_allow_natives_syntax = true;
CcTest::InitializeVM();
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
Isolate* isolate = CcTest::i_isolate();
CompileRun(
"function min() { return Math.min.apply(null, arguments); }"
"function f(x) { return min(x, 0); }"
"%PrepareFunctionForOptimization(min);"
"%PrepareFunctionForOptimization(f);"
"f(1);");
Handle<JSFunction> min = GetFunction("min");
Handle<FeedbackVector> feedback_vector =
Handle<FeedbackVector>(min->feedback_vector(), isolate);
FeedbackSlot slot(6);
FeedbackNexus nexus(feedback_vector, slot);
CHECK_EQ(MONOMORPHIC, nexus.ic_state());
CHECK_EQ(SpeculationMode::kAllowSpeculation, nexus.GetSpeculationMode());
CHECK_EQ(CallFeedbackContent::kReceiver, nexus.GetCallFeedbackContent());
CompileRun("%OptimizeFunctionOnNextCall(f); f(1);");
CHECK_EQ(MONOMORPHIC, nexus.ic_state());
CHECK_EQ(SpeculationMode::kAllowSpeculation, nexus.GetSpeculationMode());
CHECK_EQ(CallFeedbackContent::kReceiver, nexus.GetCallFeedbackContent());
CompileRun("f({});"); // Deoptimizes.
CHECK_EQ(MONOMORPHIC, nexus.ic_state());
CHECK_EQ(SpeculationMode::kDisallowSpeculation, nexus.GetSpeculationMode());
CHECK_EQ(CallFeedbackContent::kReceiver, nexus.GetCallFeedbackContent());
}
TEST(VectorLoadICStates) { TEST(VectorLoadICStates) {
if (!i::FLAG_use_ic) return; if (!i::FLAG_use_ic) return;
if (i::FLAG_always_opt) return; if (i::FLAG_always_opt) return;
......
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