Index: src/full-codegen/x64/full-codegen-x64.cc |
diff --git a/src/full-codegen/x64/full-codegen-x64.cc b/src/full-codegen/x64/full-codegen-x64.cc |
index 790d9d65a4f0734aea80a9637dce968b998eadc2..264c298579a4f729fdf02ad67612c1dab6566138 100644 |
--- a/src/full-codegen/x64/full-codegen-x64.cc |
+++ b/src/full-codegen/x64/full-codegen-x64.cc |
@@ -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. |