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); |
{ |