Commit 0637f5f6 authored by bmeurer's avatar bmeurer Committed by Commit bot

[for-in] Ensure that we learn from deopts within for-in loop bodies.

If we deoptimize from TurboFan or Crankshaft into the body of a for-in
loop and that for-in mode then switches to slow mode (i.e. has to call
%ForInFilter), we have to record that feedback, because otherwise we
might actually OSR into that loop assuming that it's fast mode still,
or even worse recompile the function later when we call it again w/o
having rerun the for-in loop in fullcodegen from the beginning (where
was previously the only place we could learn).

R=mstarzinger@chromium.org
BUG=v8:3650
LOG=n

Review URL: https://codereview.chromium.org/1638303008

Cr-Commit-Position: refs/heads/master@{#33612}
parent b35a7aaf
......@@ -1118,9 +1118,9 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// We got a fixed array in register r0. Iterate through that.
__ bind(&fixed_array);
int const vector_index = SmiFromSlot(slot)->value();
__ EmitLoadTypeFeedbackVector(r1);
__ mov(r2, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate())));
int vector_index = SmiFromSlot(slot)->value();
__ str(r2, FieldMemOperand(r1, FixedArray::OffsetOfElementAt(vector_index)));
__ mov(r1, Operand(Smi::FromInt(1))); // Smi(1) indicates slow check
__ Push(r1, r0); // Smi and array
......@@ -1156,6 +1156,16 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
__ cmp(r4, Operand(r2));
__ b(eq, &update_each);
// We might get here from TurboFan or Crankshaft when something in the
// for-in loop body deopts and only now notice in fullcodegen, that we
// can now longer use the enum cache, i.e. left fast mode. So better record
// this information here, in case we later OSR back into this loop or
// reoptimize the whole function w/o rerunning the loop with the slow
// mode object in fullcodegen (which would result in a deopt loop).
__ EmitLoadTypeFeedbackVector(r0);
__ mov(r2, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate())));
__ str(r2, FieldMemOperand(r0, FixedArray::OffsetOfElementAt(vector_index)));
// Convert the entry to a string or (smi) 0 if it isn't a property
// any more. If the property has been removed while iterating, we
// just skip it.
......
......@@ -1114,9 +1114,9 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// We got a fixed array in register x0. Iterate through that.
__ Bind(&fixed_array);
int const vector_index = SmiFromSlot(slot)->value();
__ EmitLoadTypeFeedbackVector(x1);
__ Mov(x10, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate())));
int vector_index = SmiFromSlot(slot)->value();
__ Str(x10, FieldMemOperand(x1, FixedArray::OffsetOfElementAt(vector_index)));
__ Mov(x1, Smi::FromInt(1)); // Smi(1) indicates slow check.
__ Ldr(x2, FieldMemOperand(x0, FixedArray::kLengthOffset));
......@@ -1150,6 +1150,16 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
__ Cmp(x11, x2);
__ B(eq, &update_each);
// We might get here from TurboFan or Crankshaft when something in the
// for-in loop body deopts and only now notice in fullcodegen, that we
// can now longer use the enum cache, i.e. left fast mode. So better record
// this information here, in case we later OSR back into this loop or
// reoptimize the whole function w/o rerunning the loop with the slow
// mode object in fullcodegen (which would result in a deopt loop).
__ EmitLoadTypeFeedbackVector(x0);
__ Mov(x10, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate())));
__ Str(x10, FieldMemOperand(x0, FixedArray::OffsetOfElementAt(vector_index)));
// Convert the entry to a string or (smi) 0 if it isn't a property
// any more. If the property has been removed while iterating, we
// just skip it.
......
......@@ -1047,8 +1047,8 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
__ bind(&fixed_array);
// No need for a write barrier, we are storing a Smi in the feedback vector.
int const vector_index = SmiFromSlot(slot)->value();
__ EmitLoadTypeFeedbackVector(ebx);
int vector_index = SmiFromSlot(slot)->value();
__ mov(FieldOperand(ebx, FixedArray::OffsetOfElementAt(vector_index)),
Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate())));
__ push(Immediate(Smi::FromInt(1))); // Smi(1) indicates slow check
......@@ -1081,6 +1081,16 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
__ cmp(edx, FieldOperand(ecx, HeapObject::kMapOffset));
__ j(equal, &update_each, Label::kNear);
// We might get here from TurboFan or Crankshaft when something in the
// for-in loop body deopts and only now notice in fullcodegen, that we
// can now longer use the enum cache, i.e. left fast mode. So better record
// this information here, in case we later OSR back into this loop or
// reoptimize the whole function w/o rerunning the loop with the slow
// mode object in fullcodegen (which would result in a deopt loop).
__ EmitLoadTypeFeedbackVector(edx);
__ mov(FieldOperand(edx, FixedArray::OffsetOfElementAt(vector_index)),
Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate())));
// Convert the entry to a string or null if it isn't a property
// anymore. If the property has been removed while iterating, we
// just skip it.
......
......@@ -1114,9 +1114,9 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// We got a fixed array in register v0. Iterate through that.
__ bind(&fixed_array);
int const vector_index = SmiFromSlot(slot)->value();
__ EmitLoadTypeFeedbackVector(a1);
__ li(a2, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate())));
int vector_index = SmiFromSlot(slot)->value();
__ sw(a2, FieldMemOperand(a1, FixedArray::OffsetOfElementAt(vector_index)));
__ li(a1, Operand(Smi::FromInt(1))); // Smi(1) indicates slow check
......@@ -1153,6 +1153,16 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
__ lw(t0, FieldMemOperand(a1, HeapObject::kMapOffset));
__ Branch(&update_each, eq, t0, Operand(a2));
// We might get here from TurboFan or Crankshaft when something in the
// for-in loop body deopts and only now notice in fullcodegen, that we
// can now longer use the enum cache, i.e. left fast mode. So better record
// this information here, in case we later OSR back into this loop or
// reoptimize the whole function w/o rerunning the loop with the slow
// mode object in fullcodegen (which would result in a deopt loop).
__ EmitLoadTypeFeedbackVector(a0);
__ li(a2, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate())));
__ sw(a2, FieldMemOperand(a0, FixedArray::OffsetOfElementAt(vector_index)));
// Convert the entry to a string or (smi) 0 if it isn't a property
// any more. If the property has been removed while iterating, we
// just skip it.
......
......@@ -1114,9 +1114,9 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// We got a fixed array in register v0. Iterate through that.
__ bind(&fixed_array);
int const vector_index = SmiFromSlot(slot)->value();
__ EmitLoadTypeFeedbackVector(a1);
__ li(a2, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate())));
int vector_index = SmiFromSlot(slot)->value();
__ sd(a2, FieldMemOperand(a1, FixedArray::OffsetOfElementAt(vector_index)));
__ li(a1, Operand(Smi::FromInt(1))); // Smi(1) indicates slow check
......@@ -1154,6 +1154,16 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
__ ld(a4, FieldMemOperand(a1, HeapObject::kMapOffset));
__ Branch(&update_each, eq, a4, Operand(a2));
// We might get here from TurboFan or Crankshaft when something in the
// for-in loop body deopts and only now notice in fullcodegen, that we
// can now longer use the enum cache, i.e. left fast mode. So better record
// this information here, in case we later OSR back into this loop or
// reoptimize the whole function w/o rerunning the loop with the slow
// mode object in fullcodegen (which would result in a deopt loop).
__ EmitLoadTypeFeedbackVector(a0);
__ li(a2, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate())));
__ sd(a2, FieldMemOperand(a0, FixedArray::OffsetOfElementAt(vector_index)));
// Convert the entry to a string or (smi) 0 if it isn't a property
// any more. If the property has been removed while iterating, we
// just skip it.
......
......@@ -1068,8 +1068,8 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
__ bind(&fixed_array);
// No need for a write barrier, we are storing a Smi in the feedback vector.
int const vector_index = SmiFromSlot(slot)->value();
__ EmitLoadTypeFeedbackVector(rbx);
int vector_index = SmiFromSlot(slot)->value();
__ Move(FieldOperand(rbx, FixedArray::OffsetOfElementAt(vector_index)),
TypeFeedbackVector::MegamorphicSentinel(isolate()));
__ movp(rcx, Operand(rsp, 0 * kPointerSize)); // Get enumerated object
......@@ -1107,6 +1107,16 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
__ cmpp(rdx, FieldOperand(rcx, HeapObject::kMapOffset));
__ j(equal, &update_each, Label::kNear);
// We might get here from TurboFan or Crankshaft when something in the
// for-in loop body deopts and only now notice in fullcodegen, that we
// can now longer use the enum cache, i.e. left fast mode. So better record
// this information here, in case we later OSR back into this loop or
// reoptimize the whole function w/o rerunning the loop with the slow
// mode object in fullcodegen (which would result in a deopt loop).
__ EmitLoadTypeFeedbackVector(rdx);
__ Move(FieldOperand(rdx, FixedArray::OffsetOfElementAt(vector_index)),
TypeFeedbackVector::MegamorphicSentinel(isolate()));
// Convert the entry to a string or null if it isn't a property
// anymore. If the property has been removed while iterating, we
// just skip it.
......
......@@ -1039,8 +1039,8 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
__ bind(&fixed_array);
// No need for a write barrier, we are storing a Smi in the feedback vector.
int const vector_index = SmiFromSlot(slot)->value();
__ EmitLoadTypeFeedbackVector(ebx);
int vector_index = SmiFromSlot(slot)->value();
__ mov(FieldOperand(ebx, FixedArray::OffsetOfElementAt(vector_index)),
Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate())));
__ push(Immediate(Smi::FromInt(1))); // Smi(1) undicates slow check
......@@ -1073,6 +1073,16 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
__ cmp(edx, FieldOperand(ecx, HeapObject::kMapOffset));
__ j(equal, &update_each, Label::kNear);
// We might get here from TurboFan or Crankshaft when something in the
// for-in loop body deopts and only now notice in fullcodegen, that we
// can now longer use the enum cache, i.e. left fast mode. So better record
// this information here, in case we later OSR back into this loop or
// reoptimize the whole function w/o rerunning the loop with the slow
// mode object in fullcodegen (which would result in a deopt loop).
__ EmitLoadTypeFeedbackVector(edx);
__ mov(FieldOperand(edx, FixedArray::OffsetOfElementAt(vector_index)),
Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate())));
// Convert the entry to a string or null if it isn't a property
// anymore. If the property has been removed while iterating, we
// just skip it.
......
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