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

Side by Side Diff: src/hydrogen.cc

Issue 1086333002: Reland "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: Just give up if null or undefined. 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 | « src/hydrogen.h ('k') | src/ia32/lithium-codegen-ia32.cc » ('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 5033 matching lines...) Expand 10 before | Expand all | Expand 10 after
5044 5044
5045 void HOptimizedGraphBuilder::VisitForInStatement(ForInStatement* stmt) { 5045 void HOptimizedGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
5046 DCHECK(!HasStackOverflow()); 5046 DCHECK(!HasStackOverflow());
5047 DCHECK(current_block() != NULL); 5047 DCHECK(current_block() != NULL);
5048 DCHECK(current_block()->HasPredecessor()); 5048 DCHECK(current_block()->HasPredecessor());
5049 5049
5050 if (!FLAG_optimize_for_in) { 5050 if (!FLAG_optimize_for_in) {
5051 return Bailout(kForInStatementOptimizationIsDisabled); 5051 return Bailout(kForInStatementOptimizationIsDisabled);
5052 } 5052 }
5053 5053
5054 if (stmt->for_in_type() != ForInStatement::FAST_FOR_IN) {
5055 return Bailout(kForInStatementIsNotFastCase);
5056 }
5057
5058 if (!stmt->each()->IsVariableProxy() || 5054 if (!stmt->each()->IsVariableProxy() ||
5059 !stmt->each()->AsVariableProxy()->var()->IsStackLocal()) { 5055 !stmt->each()->AsVariableProxy()->var()->IsStackLocal()) {
5060 return Bailout(kForInStatementWithNonLocalEachVariable); 5056 return Bailout(kForInStatementWithNonLocalEachVariable);
5061 } 5057 }
5062 5058
5063 Variable* each_var = stmt->each()->AsVariableProxy()->var(); 5059 Variable* each_var = stmt->each()->AsVariableProxy()->var();
5064 5060
5065 CHECK_ALIVE(VisitForValue(stmt->enumerable())); 5061 CHECK_ALIVE(VisitForValue(stmt->enumerable()));
5066 HValue* enumerable = Top(); // Leave enumerable at the top. 5062 HValue* enumerable = Top(); // Leave enumerable at the top.
5067 5063
5068 HInstruction* map = Add<HForInPrepareMap>(enumerable); 5064 IfBuilder if_undefined_or_null(this);
5069 Add<HSimulate>(stmt->PrepareId()); 5065 if_undefined_or_null.If<HCompareObjectEqAndBranch>(
5066 enumerable, graph()->GetConstantUndefined());
5067 if_undefined_or_null.Or();
5068 if_undefined_or_null.If<HCompareObjectEqAndBranch>(
5069 enumerable, graph()->GetConstantNull());
5070 if_undefined_or_null.ThenDeopt(Deoptimizer::kUndefinedOrNullInForIn);
5071 if_undefined_or_null.End();
5072 BuildForInBody(stmt, each_var, enumerable);
5073 }
5070 5074
5071 HInstruction* array = Add<HForInCacheArray>(
5072 enumerable, map, DescriptorArray::kEnumCacheBridgeCacheIndex);
5073 5075
5074 HInstruction* enum_length = Add<HMapEnumLength>(map); 5076 void HOptimizedGraphBuilder::BuildForInBody(ForInStatement* stmt,
5077 Variable* each_var,
5078 HValue* enumerable) {
5079 HInstruction* map;
5080 HInstruction* array;
5081 HInstruction* enum_length;
5082 bool fast = stmt->for_in_type() == ForInStatement::FAST_FOR_IN;
5083 if (fast) {
5084 map = Add<HForInPrepareMap>(enumerable);
5085 Add<HSimulate>(stmt->PrepareId());
5086
5087 array = Add<HForInCacheArray>(enumerable, map,
5088 DescriptorArray::kEnumCacheBridgeCacheIndex);
5089 enum_length = Add<HMapEnumLength>(map);
5090
5091 HInstruction* index_cache = Add<HForInCacheArray>(
5092 enumerable, map, DescriptorArray::kEnumCacheBridgeIndicesCacheIndex);
5093 HForInCacheArray::cast(array)
5094 ->set_index_cache(HForInCacheArray::cast(index_cache));
5095 } else {
5096 Add<HSimulate>(stmt->PrepareId());
5097 {
5098 NoObservableSideEffectsScope no_effects(this);
5099 BuildJSObjectCheck(enumerable, 0);
5100 }
5101 Add<HSimulate>(stmt->ToObjectId());
5102
5103 map = graph()->GetConstant1();
5104 Runtime::FunctionId function_id = Runtime::kGetPropertyNamesFast;
5105 Add<HPushArguments>(enumerable);
5106 array = Add<HCallRuntime>(isolate()->factory()->empty_string(),
5107 Runtime::FunctionForId(function_id), 1);
5108 Push(array);
5109 Add<HSimulate>(stmt->EnumId());
5110 Drop(1);
5111 Handle<Map> array_map = isolate()->factory()->fixed_array_map();
5112 HValue* check = Add<HCheckMaps>(array, array_map);
5113 enum_length = AddLoadFixedArrayLength(array, check);
5114 }
5075 5115
5076 HInstruction* start_index = Add<HConstant>(0); 5116 HInstruction* start_index = Add<HConstant>(0);
5077 5117
5078 Push(map); 5118 Push(map);
5079 Push(array); 5119 Push(array);
5080 Push(enum_length); 5120 Push(enum_length);
5081 Push(start_index); 5121 Push(start_index);
5082 5122
5083 HInstruction* index_cache = Add<HForInCacheArray>(
5084 enumerable, map, DescriptorArray::kEnumCacheBridgeIndicesCacheIndex);
5085 HForInCacheArray::cast(array)
5086 ->set_index_cache(HForInCacheArray::cast(index_cache));
5087
5088 HBasicBlock* loop_entry = BuildLoopEntry(stmt); 5123 HBasicBlock* loop_entry = BuildLoopEntry(stmt);
5089 5124
5125 // Reload the values to ensure we have up-to-date values inside of the loop.
5126 // This is relevant especially for OSR where the values don't come from the
5127 // computation above, but from the OSR entry block.
5128 enumerable = environment()->ExpressionStackAt(4);
5090 HValue* index = environment()->ExpressionStackAt(0); 5129 HValue* index = environment()->ExpressionStackAt(0);
5091 HValue* limit = environment()->ExpressionStackAt(1); 5130 HValue* limit = environment()->ExpressionStackAt(1);
5092 5131
5093 // Check that we still have more keys. 5132 // Check that we still have more keys.
5094 HCompareNumericAndBranch* compare_index = 5133 HCompareNumericAndBranch* compare_index =
5095 New<HCompareNumericAndBranch>(index, limit, Token::LT); 5134 New<HCompareNumericAndBranch>(index, limit, Token::LT);
5096 compare_index->set_observed_input_representation( 5135 compare_index->set_observed_input_representation(
5097 Representation::Smi(), Representation::Smi()); 5136 Representation::Smi(), Representation::Smi());
5098 5137
5099 HBasicBlock* loop_body = graph()->CreateBasicBlock(); 5138 HBasicBlock* loop_body = graph()->CreateBasicBlock();
5100 HBasicBlock* loop_successor = graph()->CreateBasicBlock(); 5139 HBasicBlock* loop_successor = graph()->CreateBasicBlock();
5101 5140
5102 compare_index->SetSuccessorAt(0, loop_body); 5141 compare_index->SetSuccessorAt(0, loop_body);
5103 compare_index->SetSuccessorAt(1, loop_successor); 5142 compare_index->SetSuccessorAt(1, loop_successor);
5104 FinishCurrentBlock(compare_index); 5143 FinishCurrentBlock(compare_index);
5105 5144
5106 set_current_block(loop_successor); 5145 set_current_block(loop_successor);
5107 Drop(5); 5146 Drop(5);
5108 5147
5109 set_current_block(loop_body); 5148 set_current_block(loop_body);
5110 5149
5111 HValue* key = 5150 HValue* key =
5112 Add<HLoadKeyed>(environment()->ExpressionStackAt(2), // Enum cache. 5151 Add<HLoadKeyed>(environment()->ExpressionStackAt(2), // Enum cache.
5113 environment()->ExpressionStackAt(0), // Iteration index. 5152 index, index, FAST_ELEMENTS);
5114 environment()->ExpressionStackAt(0), FAST_ELEMENTS);
5115 5153
5116 // Check if the expected map still matches that of the enumerable. 5154 if (fast) {
5117 // If not just deoptimize. 5155 // Check if the expected map still matches that of the enumerable.
5118 Add<HCheckMapValue>(environment()->ExpressionStackAt(4), 5156 // If not just deoptimize.
5119 environment()->ExpressionStackAt(3)); 5157 Add<HCheckMapValue>(enumerable, environment()->ExpressionStackAt(3));
5120 5158 Bind(each_var, key);
5121 Bind(each_var, key); 5159 } else {
5160 HValue* function = AddLoadJSBuiltin(Builtins::FILTER_KEY);
5161 Add<HPushArguments>(enumerable, key);
5162 key = Add<HInvokeFunction>(function, 2);
5163 Bind(each_var, key);
5164 Add<HSimulate>(stmt->AssignmentId());
5165 Add<HCheckHeapObject>(key);
5166 }
5122 5167
5123 BreakAndContinueInfo break_info(stmt, scope(), 5); 5168 BreakAndContinueInfo break_info(stmt, scope(), 5);
5124 { 5169 {
5125 BreakAndContinueScope push(&break_info, this); 5170 BreakAndContinueScope push(&break_info, this);
5126 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry)); 5171 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry));
5127 } 5172 }
5128 5173
5129 HBasicBlock* body_exit = 5174 HBasicBlock* body_exit =
5130 JoinContinue(stmt, current_block(), break_info.continue_block()); 5175 JoinContinue(stmt, current_block(), break_info.continue_block());
5131 5176
(...skipping 7787 matching lines...) Expand 10 before | Expand all | Expand 10 after
12919 if (ShouldProduceTraceOutput()) { 12964 if (ShouldProduceTraceOutput()) {
12920 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 12965 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
12921 } 12966 }
12922 12967
12923 #ifdef DEBUG 12968 #ifdef DEBUG
12924 graph_->Verify(false); // No full verify. 12969 graph_->Verify(false); // No full verify.
12925 #endif 12970 #endif
12926 } 12971 }
12927 12972
12928 } } // namespace v8::internal 12973 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/ia32/lithium-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698