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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « no previous file | test/mjsunit/for-in-opt.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/hydrogen.h" 5 #include "src/hydrogen.h"
6 6
7 #include <sstream> 7 #include <sstream>
8 8
9 #include "src/v8.h" 9 #include "src/v8.h"
10 10
(...skipping 5032 matching lines...) Expand 10 before | Expand all | Expand 10 after
5043 5043
5044 void HOptimizedGraphBuilder::VisitForInStatement(ForInStatement* stmt) { 5044 void HOptimizedGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
5045 DCHECK(!HasStackOverflow()); 5045 DCHECK(!HasStackOverflow());
5046 DCHECK(current_block() != NULL); 5046 DCHECK(current_block() != NULL);
5047 DCHECK(current_block()->HasPredecessor()); 5047 DCHECK(current_block()->HasPredecessor());
5048 5048
5049 if (!FLAG_optimize_for_in) { 5049 if (!FLAG_optimize_for_in) {
5050 return Bailout(kForInStatementOptimizationIsDisabled); 5050 return Bailout(kForInStatementOptimizationIsDisabled);
5051 } 5051 }
5052 5052
5053 if (stmt->for_in_type() != ForInStatement::FAST_FOR_IN) {
5054 return Bailout(kForInStatementIsNotFastCase);
5055 }
5056
5057 if (!stmt->each()->IsVariableProxy() || 5053 if (!stmt->each()->IsVariableProxy() ||
5058 !stmt->each()->AsVariableProxy()->var()->IsStackLocal()) { 5054 !stmt->each()->AsVariableProxy()->var()->IsStackLocal()) {
5059 return Bailout(kForInStatementWithNonLocalEachVariable); 5055 return Bailout(kForInStatementWithNonLocalEachVariable);
5060 } 5056 }
5061 5057
5062 Variable* each_var = stmt->each()->AsVariableProxy()->var(); 5058 Variable* each_var = stmt->each()->AsVariableProxy()->var();
5063 5059
5064 CHECK_ALIVE(VisitForValue(stmt->enumerable())); 5060 CHECK_ALIVE(VisitForValue(stmt->enumerable()));
5065 HValue* enumerable = Top(); // Leave enumerable at the top. 5061 HValue* enumerable = Top(); // Leave enumerable at the top.
5066 5062
5067 HInstruction* map = Add<HForInPrepareMap>(enumerable); 5063 HInstruction* map;
5068 Add<HSimulate>(stmt->PrepareId()); 5064 HInstruction* array;
5065 HInstruction* enum_length;
5066 bool fast = stmt->for_in_type() == ForInStatement::FAST_FOR_IN;
5067 if (fast) {
5068 map = Add<HForInPrepareMap>(enumerable);
5069 Add<HSimulate>(stmt->PrepareId());
5069 5070
5070 HInstruction* array = Add<HForInCacheArray>( 5071 array = Add<HForInCacheArray>(enumerable, map,
5071 enumerable, map, DescriptorArray::kEnumCacheBridgeCacheIndex); 5072 DescriptorArray::kEnumCacheBridgeCacheIndex);
5073 enum_length = Add<HMapEnumLength>(map);
5072 5074
5073 HInstruction* enum_length = Add<HMapEnumLength>(map); 5075 HInstruction* index_cache = Add<HForInCacheArray>(
5076 enumerable, map, DescriptorArray::kEnumCacheBridgeIndicesCacheIndex);
5077 HForInCacheArray::cast(array)
5078 ->set_index_cache(HForInCacheArray::cast(index_cache));
5079 } else {
5080 Add<HSimulate>(stmt->PrepareId());
5081 {
5082 NoObservableSideEffectsScope no_effects(this);
5083 BuildJSObjectCheck(enumerable, 0);
5084 }
5085 Add<HSimulate>(stmt->ToObjectId());
5086
5087 map = graph()->GetConstant1();
5088 Runtime::FunctionId function_id = Runtime::kGetPropertyNamesFast;
5089 Add<HPushArguments>(enumerable);
5090 array = Add<HCallRuntime>(isolate()->factory()->empty_string(),
5091 Runtime::FunctionForId(function_id), 1);
5092 Push(array);
5093 Add<HSimulate>(stmt->EnumId());
5094 Drop(1);
5095 Handle<Map> array_map = isolate()->factory()->fixed_array_map();
5096 HValue* check = Add<HCheckMaps>(array, array_map);
5097 enum_length = AddLoadFixedArrayLength(array, check);
5098 }
5074 5099
5075 HInstruction* start_index = Add<HConstant>(0); 5100 HInstruction* start_index = Add<HConstant>(0);
5076 5101
5077 Push(map); 5102 Push(map);
5078 Push(array); 5103 Push(array);
5079 Push(enum_length); 5104 Push(enum_length);
5080 Push(start_index); 5105 Push(start_index);
5081 5106
5082 HInstruction* index_cache = Add<HForInCacheArray>(
5083 enumerable, map, DescriptorArray::kEnumCacheBridgeIndicesCacheIndex);
5084 HForInCacheArray::cast(array)->set_index_cache(
5085 HForInCacheArray::cast(index_cache));
5086
5087 HBasicBlock* loop_entry = BuildLoopEntry(stmt); 5107 HBasicBlock* loop_entry = BuildLoopEntry(stmt);
5088 5108
5109 // Reload the values to ensure we have up-to-date values inside of the loop.
5110 // This is relevant especially for OSR where the values don't come from the
5111 // computation above, but from the OSR entry block.
5112 enumerable = environment()->ExpressionStackAt(4);
5089 HValue* index = environment()->ExpressionStackAt(0); 5113 HValue* index = environment()->ExpressionStackAt(0);
5090 HValue* limit = environment()->ExpressionStackAt(1); 5114 HValue* limit = environment()->ExpressionStackAt(1);
5091 5115
5092 // Check that we still have more keys. 5116 // Check that we still have more keys.
5093 HCompareNumericAndBranch* compare_index = 5117 HCompareNumericAndBranch* compare_index =
5094 New<HCompareNumericAndBranch>(index, limit, Token::LT); 5118 New<HCompareNumericAndBranch>(index, limit, Token::LT);
5095 compare_index->set_observed_input_representation( 5119 compare_index->set_observed_input_representation(
5096 Representation::Smi(), Representation::Smi()); 5120 Representation::Smi(), Representation::Smi());
5097 5121
5098 HBasicBlock* loop_body = graph()->CreateBasicBlock(); 5122 HBasicBlock* loop_body = graph()->CreateBasicBlock();
5099 HBasicBlock* loop_successor = graph()->CreateBasicBlock(); 5123 HBasicBlock* loop_successor = graph()->CreateBasicBlock();
5100 5124
5101 compare_index->SetSuccessorAt(0, loop_body); 5125 compare_index->SetSuccessorAt(0, loop_body);
5102 compare_index->SetSuccessorAt(1, loop_successor); 5126 compare_index->SetSuccessorAt(1, loop_successor);
5103 FinishCurrentBlock(compare_index); 5127 FinishCurrentBlock(compare_index);
5104 5128
5105 set_current_block(loop_successor); 5129 set_current_block(loop_successor);
5106 Drop(5); 5130 Drop(5);
5107 5131
5108 set_current_block(loop_body); 5132 set_current_block(loop_body);
5109 5133
5110 HValue* key = Add<HLoadKeyed>( 5134 HValue* key =
5111 environment()->ExpressionStackAt(2), // Enum cache. 5135 Add<HLoadKeyed>(environment()->ExpressionStackAt(2), // Enum cache.
5112 environment()->ExpressionStackAt(0), // Iteration index. 5136 index, index, FAST_ELEMENTS);
5113 environment()->ExpressionStackAt(0),
5114 FAST_ELEMENTS);
5115 5137
5116 // Check if the expected map still matches that of the enumerable. 5138 if (fast) {
5117 // If not just deoptimize. 5139 // Check if the expected map still matches that of the enumerable.
5118 Add<HCheckMapValue>(environment()->ExpressionStackAt(4), 5140 // If not just deoptimize.
5119 environment()->ExpressionStackAt(3)); 5141 Add<HCheckMapValue>(enumerable, environment()->ExpressionStackAt(3));
5120 5142 Bind(each_var, key);
5121 Bind(each_var, key); 5143 } else {
5144 HValue* function = AddLoadJSBuiltin(Builtins::FILTER_KEY);
5145 Add<HPushArguments>(enumerable, key);
5146 key = Add<HInvokeFunction>(function, 2);
5147 Bind(each_var, key);
5148 Add<HSimulate>(stmt->AssignmentId());
5149 Add<HCheckHeapObject>(key);
5150 }
5122 5151
5123 BreakAndContinueInfo break_info(stmt, scope(), 5); 5152 BreakAndContinueInfo break_info(stmt, scope(), 5);
5124 { 5153 {
5125 BreakAndContinueScope push(&break_info, this); 5154 BreakAndContinueScope push(&break_info, this);
5126 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry)); 5155 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry));
5127 } 5156 }
5128 5157
5129 HBasicBlock* body_exit = 5158 HBasicBlock* body_exit =
5130 JoinContinue(stmt, current_block(), break_info.continue_block()); 5159 JoinContinue(stmt, current_block(), break_info.continue_block());
5131 5160
(...skipping 7790 matching lines...) Expand 10 before | Expand all | Expand 10 after
12922 if (ShouldProduceTraceOutput()) { 12951 if (ShouldProduceTraceOutput()) {
12923 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 12952 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
12924 } 12953 }
12925 12954
12926 #ifdef DEBUG 12955 #ifdef DEBUG
12927 graph_->Verify(false); // No full verify. 12956 graph_->Verify(false); // No full verify.
12928 #endif 12957 #endif
12929 } 12958 }
12930 12959
12931 } } // namespace v8::internal 12960 } } // namespace v8::internal
OLDNEW
« 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