Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(407)

Unified Diff: src/hydrogen.cc

Issue 1075933003: Add basic crankshaft support for slow-mode for-in to avoid disabling optimizations (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Disable for-in-opt for turbofan Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | test/mjsunit/for-in-opt.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index d6cbc1444ad52eac67ab0f98ecd35f3a8e3943ae..a20343d6d45c68c784404fc0c1c53060c346e0e9 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -5050,10 +5050,6 @@ 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);
@@ -5064,13 +5060,42 @@ void HOptimizedGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
CHECK_ALIVE(VisitForValue(stmt->enumerable()));
HValue* enumerable = Top(); // Leave enumerable at the top.
- HInstruction* map = Add<HForInPrepareMap>(enumerable);
- Add<HSimulate>(stmt->PrepareId());
-
- HInstruction* array = Add<HForInCacheArray>(
- enumerable, map, DescriptorArray::kEnumCacheBridgeCacheIndex);
+ 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* enum_length = Add<HMapEnumLength>(map);
+ 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* start_index = Add<HConstant>(0);
@@ -5079,13 +5104,12 @@ 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);
@@ -5107,18 +5131,23 @@ void HOptimizedGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
set_current_block(loop_body);
- HValue* key = Add<HLoadKeyed>(
- environment()->ExpressionStackAt(2), // Enum cache.
- environment()->ExpressionStackAt(0), // Iteration index.
- environment()->ExpressionStackAt(0),
- FAST_ELEMENTS);
+ HValue* key =
+ Add<HLoadKeyed>(environment()->ExpressionStackAt(2), // Enum cache.
+ index, index, FAST_ELEMENTS);
- // 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);
+ 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);
+ }
BreakAndContinueInfo break_info(stmt, scope(), 5);
{
« no previous file with comments | « no previous file | test/mjsunit/for-in-opt.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698