| Index: src/crankshaft/hydrogen.cc
|
| diff --git a/src/crankshaft/hydrogen.cc b/src/crankshaft/hydrogen.cc
|
| index 57478f7cc6a504fc6f38e5ace3f8aa1f2d9759d8..1836fe6b30ce875d8fdd53181c4fa9a5531119ac 100644
|
| --- a/src/crankshaft/hydrogen.cc
|
| +++ b/src/crankshaft/hydrogen.cc
|
| @@ -5377,9 +5377,11 @@ void HOptimizedGraphBuilder::BuildForInBody(ForInStatement* stmt,
|
| // Reload the values to ensure we have up-to-date values inside of the loop.
|
| // This is relevant especially for OSR where the values don't come from the
|
| // computation above, but from the OSR entry block.
|
| - enumerable = environment()->ExpressionStackAt(4);
|
| HValue* index = environment()->ExpressionStackAt(0);
|
| HValue* limit = environment()->ExpressionStackAt(1);
|
| + HValue* array = environment()->ExpressionStackAt(2);
|
| + HValue* type = environment()->ExpressionStackAt(3);
|
| + enumerable = environment()->ExpressionStackAt(4);
|
|
|
| // Check that we still have more keys.
|
| HCompareNumericAndBranch* compare_index =
|
| @@ -5399,21 +5401,31 @@ void HOptimizedGraphBuilder::BuildForInBody(ForInStatement* stmt,
|
|
|
| set_current_block(loop_body);
|
|
|
| - HValue* key =
|
| - Add<HLoadKeyed>(environment()->ExpressionStackAt(2), // Enum cache.
|
| - index, index, nullptr, FAST_ELEMENTS);
|
| + HValue* key = Add<HLoadKeyed>(array, index, index, nullptr, FAST_ELEMENTS);
|
|
|
| if (fast) {
|
| // Check if the expected map still matches that of the enumerable.
|
| // If not just deoptimize.
|
| - Add<HCheckMapValue>(enumerable, environment()->ExpressionStackAt(3));
|
| + Add<HCheckMapValue>(enumerable, type);
|
| Bind(each_var, key);
|
| } else {
|
| - Add<HPushArguments>(enumerable, key);
|
| - Runtime::FunctionId function_id = Runtime::kForInFilter;
|
| - key = Add<HCallRuntime>(Runtime::FunctionForId(function_id), 2);
|
| - Push(key);
|
| - Add<HSimulate>(stmt->FilterId());
|
| + HValue* enumerable_map =
|
| + Add<HLoadNamedField>(enumerable, nullptr, HObjectAccess::ForMap());
|
| + IfBuilder if_fast(this);
|
| + if_fast.If<HCompareObjectEqAndBranch>(enumerable_map, type);
|
| + if_fast.Then();
|
| + {
|
| + Push(key);
|
| + Add<HSimulate>(stmt->FilterId());
|
| + }
|
| + if_fast.Else();
|
| + {
|
| + Add<HPushArguments>(enumerable, key);
|
| + Runtime::FunctionId function_id = Runtime::kForInFilter;
|
| + Push(Add<HCallRuntime>(Runtime::FunctionForId(function_id), 2));
|
| + Add<HSimulate>(stmt->FilterId());
|
| + }
|
| + if_fast.End();
|
| key = Pop();
|
| Bind(each_var, key);
|
| IfBuilder if_undefined(this);
|
|
|