Index: src/crankshaft/hydrogen.cc |
diff --git a/src/crankshaft/hydrogen.cc b/src/crankshaft/hydrogen.cc |
index 3df77c01ad5153fa24d8f47fecb727f82913ce5c..53032073be238ff30dfbd879f5ae3603aed71faa 100644 |
--- a/src/crankshaft/hydrogen.cc |
+++ b/src/crankshaft/hydrogen.cc |
@@ -5311,19 +5311,19 @@ void HOptimizedGraphBuilder::VisitForInStatement(ForInStatement* stmt) { |
void HOptimizedGraphBuilder::BuildForInBody(ForInStatement* stmt, |
Variable* each_var, |
HValue* enumerable) { |
- HInstruction* map; |
- HInstruction* array; |
- HInstruction* enum_length; |
+ HValue* map; |
+ HValue* array; |
+ HValue* enum_length; |
+ Handle<Map> meta_map = isolate()->factory()->meta_map(); |
+ bool fast = stmt->for_in_type() == ForInStatement::FAST_FOR_IN; |
BuildCheckHeapObject(enumerable); |
Add<HCheckInstanceType>(enumerable, HCheckInstanceType::IS_JS_RECEIVER); |
Add<HSimulate>(stmt->ToObjectId()); |
- bool fast = stmt->for_in_type() == ForInStatement::FAST_FOR_IN; |
if (fast) { |
map = Add<HForInPrepareMap>(enumerable); |
Push(map); |
Add<HSimulate>(stmt->EnumId()); |
Drop(1); |
- Handle<Map> meta_map = isolate()->factory()->meta_map(); |
Add<HCheckMaps>(map, meta_map); |
array = Add<HForInCacheArray>(enumerable, map, |
@@ -5335,16 +5335,37 @@ void HOptimizedGraphBuilder::BuildForInBody(ForInStatement* stmt, |
HForInCacheArray::cast(array) |
->set_index_cache(HForInCacheArray::cast(index_cache)); |
} else { |
- map = graph()->GetConstant1(); |
Runtime::FunctionId function_id = Runtime::kGetPropertyNamesFast; |
Add<HPushArguments>(enumerable); |
array = Add<HCallRuntime>(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); |
+ { |
+ NoObservableSideEffectsScope scope(this); |
+ IfBuilder if_fast(this); |
+ if_fast.If<HCompareMap>(array, meta_map); |
+ if_fast.Then(); |
+ { |
+ HValue* cache_map = array; |
+ HForInCacheArray* cache = Add<HForInCacheArray>( |
+ enumerable, cache_map, DescriptorArray::kEnumCacheBridgeCacheIndex); |
+ enum_length = Add<HMapEnumLength>(cache_map); |
+ Push(cache_map); |
Jakob Kummerow
2016/01/28 21:34:38
Pushing the map here has no effect, as we're in th
|
+ Push(cache); |
+ Push(enum_length); |
+ } |
+ if_fast.Else(); |
+ { |
+ Push(graph()->GetConstant1()); |
+ Push(array); |
+ Push(AddLoadFixedArrayLength(array)); |
+ } |
+ if_fast.End(); |
+ enum_length = Pop(); |
+ array = Pop(); |
+ map = Pop(); |
+ } |
} |
HInstruction* start_index = Add<HConstant>(0); |