| Index: src/hydrogen.cc
|
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc
|
| index 3e87d69f24ccfb04e42a846b45106de2fac5d405..736f895a01f4e1c4b7a88b64c5132b3de55efa5e 100644
|
| --- a/src/hydrogen.cc
|
| +++ b/src/hydrogen.cc
|
| @@ -5051,6 +5051,10 @@ void HOptimizedGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
|
| return Bailout(kForInStatementOptimizationIsDisabled);
|
| }
|
|
|
| + if (stmt->for_in_type() != ForInStatement::FAST_FOR_IN) {
|
| + return Bailout(kForInStatementIsNotFastCase);
|
| + }
|
| +
|
| if (!stmt->each()->IsVariableProxy() ||
|
| !stmt->each()->AsVariableProxy()->var()->IsStackLocal()) {
|
| return Bailout(kForInStatementWithNonLocalEachVariable);
|
| @@ -5061,42 +5065,13 @@ void HOptimizedGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
|
| CHECK_ALIVE(VisitForValue(stmt->enumerable()));
|
| HValue* enumerable = Top(); // Leave enumerable at the top.
|
|
|
| - HInstruction* map;
|
| - HInstruction* array;
|
| - HInstruction* enum_length;
|
| - bool fast = stmt->for_in_type() == ForInStatement::FAST_FOR_IN;
|
| - if (fast) {
|
| - map = Add<HForInPrepareMap>(enumerable);
|
| - Add<HSimulate>(stmt->PrepareId());
|
| -
|
| - array = Add<HForInCacheArray>(enumerable, map,
|
| - DescriptorArray::kEnumCacheBridgeCacheIndex);
|
| - enum_length = Add<HMapEnumLength>(map);
|
| -
|
| - HInstruction* index_cache = Add<HForInCacheArray>(
|
| - enumerable, map, DescriptorArray::kEnumCacheBridgeIndicesCacheIndex);
|
| - HForInCacheArray::cast(array)
|
| - ->set_index_cache(HForInCacheArray::cast(index_cache));
|
| - } else {
|
| - Add<HSimulate>(stmt->PrepareId());
|
| - {
|
| - NoObservableSideEffectsScope no_effects(this);
|
| - BuildJSObjectCheck(enumerable, 0);
|
| - }
|
| - Add<HSimulate>(stmt->ToObjectId());
|
| + HInstruction* map = Add<HForInPrepareMap>(enumerable);
|
| + Add<HSimulate>(stmt->PrepareId());
|
|
|
| - map = graph()->GetConstant1();
|
| - Runtime::FunctionId function_id = Runtime::kGetPropertyNamesFast;
|
| - Add<HPushArguments>(enumerable);
|
| - array = Add<HCallRuntime>(isolate()->factory()->empty_string(),
|
| - Runtime::FunctionForId(function_id), 1);
|
| - Push(array);
|
| - Add<HSimulate>(stmt->EnumId());
|
| - Drop(1);
|
| - Handle<Map> array_map = isolate()->factory()->fixed_array_map();
|
| - HValue* check = Add<HCheckMaps>(array, array_map);
|
| - enum_length = AddLoadFixedArrayLength(array, check);
|
| - }
|
| + HInstruction* array = Add<HForInCacheArray>(
|
| + enumerable, map, DescriptorArray::kEnumCacheBridgeCacheIndex);
|
| +
|
| + HInstruction* enum_length = Add<HMapEnumLength>(map);
|
|
|
| HInstruction* start_index = Add<HConstant>(0);
|
|
|
| @@ -5105,12 +5080,13 @@ void HOptimizedGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
|
| Push(enum_length);
|
| Push(start_index);
|
|
|
| + HInstruction* index_cache = Add<HForInCacheArray>(
|
| + enumerable, map, DescriptorArray::kEnumCacheBridgeIndicesCacheIndex);
|
| + HForInCacheArray::cast(array)
|
| + ->set_index_cache(HForInCacheArray::cast(index_cache));
|
| +
|
| HBasicBlock* loop_entry = BuildLoopEntry(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);
|
|
|
| @@ -5134,21 +5110,15 @@ void HOptimizedGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
|
|
|
| HValue* key =
|
| Add<HLoadKeyed>(environment()->ExpressionStackAt(2), // Enum cache.
|
| - index, index, FAST_ELEMENTS);
|
| + environment()->ExpressionStackAt(0), // Iteration index.
|
| + environment()->ExpressionStackAt(0), 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));
|
| - Bind(each_var, key);
|
| - } else {
|
| - HValue* function = AddLoadJSBuiltin(Builtins::FILTER_KEY);
|
| - Add<HPushArguments>(enumerable, key);
|
| - key = Add<HInvokeFunction>(function, 2);
|
| - Bind(each_var, key);
|
| - Add<HSimulate>(stmt->AssignmentId());
|
| - Add<HCheckHeapObject>(key);
|
| - }
|
| + // Check if the expected map still matches that of the enumerable.
|
| + // If not just deoptimize.
|
| + Add<HCheckMapValue>(environment()->ExpressionStackAt(4),
|
| + environment()->ExpressionStackAt(3));
|
| +
|
| + Bind(each_var, key);
|
|
|
| BreakAndContinueInfo break_info(stmt, scope(), 5);
|
| {
|
|
|