Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 4056 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4067 | 4067 |
| 4068 | 4068 |
| 4069 void EffectContext::ReturnValue(HValue* value) { | 4069 void EffectContext::ReturnValue(HValue* value) { |
| 4070 // The value is simply ignored. | 4070 // The value is simply ignored. |
| 4071 } | 4071 } |
| 4072 | 4072 |
| 4073 | 4073 |
| 4074 void ValueContext::ReturnValue(HValue* value) { | 4074 void ValueContext::ReturnValue(HValue* value) { |
| 4075 // The value is tracked in the bailout environment, and communicated | 4075 // The value is tracked in the bailout environment, and communicated |
| 4076 // through the environment as the result of the expression. | 4076 // through the environment as the result of the expression. |
| 4077 if (!arguments_allowed() && value->CheckFlag(HValue::kIsArguments)) { | 4077 if (value->CheckFlag(HValue::kIsArguments)) { |
| 4078 owner()->Bailout(kBadValueContextForArgumentsValue); | 4078 if (flag_ == ARGUMENTS_FAKED) { |
| 4079 value = owner()->graph()->GetConstantUndefined(); | |
| 4080 } else if (!arguments_allowed()) { | |
| 4081 owner()->Bailout(kBadValueContextForArgumentsValue); | |
| 4082 } | |
| 4079 } | 4083 } |
| 4080 owner()->Push(value); | 4084 owner()->Push(value); |
| 4081 } | 4085 } |
| 4082 | 4086 |
| 4083 | 4087 |
| 4084 void TestContext::ReturnValue(HValue* value) { | 4088 void TestContext::ReturnValue(HValue* value) { |
| 4085 BuildBranch(value); | 4089 BuildBranch(value); |
| 4086 } | 4090 } |
| 4087 | 4091 |
| 4088 | 4092 |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4294 | 4298 |
| 4295 | 4299 |
| 4296 void HOptimizedGraphBuilder::VisitExpressions( | 4300 void HOptimizedGraphBuilder::VisitExpressions( |
| 4297 ZoneList<Expression*>* exprs) { | 4301 ZoneList<Expression*>* exprs) { |
| 4298 for (int i = 0; i < exprs->length(); ++i) { | 4302 for (int i = 0; i < exprs->length(); ++i) { |
| 4299 CHECK_ALIVE(VisitForValue(exprs->at(i))); | 4303 CHECK_ALIVE(VisitForValue(exprs->at(i))); |
| 4300 } | 4304 } |
| 4301 } | 4305 } |
| 4302 | 4306 |
| 4303 | 4307 |
| 4308 void HOptimizedGraphBuilder::VisitExpressions(ZoneList<Expression*>* exprs, | |
| 4309 ArgumentsAllowedFlag flag) { | |
| 4310 for (int i = 0; i < exprs->length(); ++i) { | |
| 4311 CHECK_ALIVE(VisitForValue(exprs->at(i), flag)); | |
| 4312 } | |
| 4313 } | |
| 4314 | |
| 4315 | |
| 4304 bool HOptimizedGraphBuilder::BuildGraph() { | 4316 bool HOptimizedGraphBuilder::BuildGraph() { |
| 4305 if (current_info()->function()->is_generator()) { | 4317 if (current_info()->function()->is_generator()) { |
| 4306 Bailout(kFunctionIsAGenerator); | 4318 Bailout(kFunctionIsAGenerator); |
| 4307 return false; | 4319 return false; |
| 4308 } | 4320 } |
| 4309 Scope* scope = current_info()->scope(); | 4321 Scope* scope = current_info()->scope(); |
| 4310 if (scope->HasIllegalRedeclaration()) { | 4322 if (scope->HasIllegalRedeclaration()) { |
| 4311 Bailout(kFunctionWithIllegalRedeclaration); | 4323 Bailout(kFunctionWithIllegalRedeclaration); |
| 4312 return false; | 4324 return false; |
| 4313 } | 4325 } |
| (...skipping 4564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8878 case kFunctionCall: { | 8890 case kFunctionCall: { |
| 8879 if (expr->arguments()->length() == 0) return false; | 8891 if (expr->arguments()->length() == 0) return false; |
| 8880 BuildFunctionCall(expr); | 8892 BuildFunctionCall(expr); |
| 8881 return true; | 8893 return true; |
| 8882 } | 8894 } |
| 8883 case kFunctionApply: { | 8895 case kFunctionApply: { |
| 8884 // For .apply, only the pattern f.apply(receiver, arguments) | 8896 // For .apply, only the pattern f.apply(receiver, arguments) |
| 8885 // is supported. | 8897 // is supported. |
| 8886 if (current_info()->scope()->arguments() == NULL) return false; | 8898 if (current_info()->scope()->arguments() == NULL) return false; |
| 8887 | 8899 |
| 8888 ZoneList<Expression*>* args = expr->arguments(); | 8900 if (!CanBeFunctionApplyArguments(expr, true)) return false; |
| 8889 if (args->length() != 2) return false; | |
| 8890 | 8901 |
| 8891 VariableProxy* arg_two = args->at(1)->AsVariableProxy(); | |
| 8892 if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false; | |
| 8893 HValue* arg_two_value = LookupAndMakeLive(arg_two->var()); | |
| 8894 if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false; | |
| 8895 BuildFunctionApply(expr); | 8902 BuildFunctionApply(expr); |
| 8896 return true; | 8903 return true; |
| 8897 } | 8904 } |
| 8898 default: { return false; } | 8905 default: { return false; } |
| 8899 } | 8906 } |
| 8900 UNREACHABLE(); | 8907 UNREACHABLE(); |
| 8901 } | 8908 } |
| 8902 | 8909 |
| 8903 | 8910 |
| 8904 void HOptimizedGraphBuilder::BuildFunctionApply(Call* expr) { | 8911 void HOptimizedGraphBuilder::BuildFunctionApply(Call* expr) { |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9171 } | 9178 } |
| 9172 | 9179 |
| 9173 BuildArrayCall(expr, | 9180 BuildArrayCall(expr, |
| 9174 expr->arguments()->length(), | 9181 expr->arguments()->length(), |
| 9175 function, | 9182 function, |
| 9176 expr->allocation_site()); | 9183 expr->allocation_site()); |
| 9177 return true; | 9184 return true; |
| 9178 } | 9185 } |
| 9179 | 9186 |
| 9180 | 9187 |
| 9188 bool HOptimizedGraphBuilder::CanBeFunctionApplyArguments( | |
| 9189 Call* expr, bool mark_arguments_as_live) { | |
| 9190 ZoneList<Expression*>* args = expr->arguments(); | |
| 9191 if (args->length() != 2) return false; | |
| 9192 VariableProxy* arg_two = args->at(1)->AsVariableProxy(); | |
| 9193 if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false; | |
| 9194 HValue* arg_two_value = mark_arguments_as_live | |
| 9195 ? LookupAndMakeLive(arg_two->var()) | |
| 9196 : Lookup(arg_two->var()); | |
| 9197 if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false; | |
| 9198 return true; | |
| 9199 } | |
| 9200 | |
| 9201 | |
| 9181 void HOptimizedGraphBuilder::VisitCall(Call* expr) { | 9202 void HOptimizedGraphBuilder::VisitCall(Call* expr) { |
| 9182 DCHECK(!HasStackOverflow()); | 9203 DCHECK(!HasStackOverflow()); |
| 9183 DCHECK(current_block() != NULL); | 9204 DCHECK(current_block() != NULL); |
| 9184 DCHECK(current_block()->HasPredecessor()); | 9205 DCHECK(current_block()->HasPredecessor()); |
| 9185 Expression* callee = expr->expression(); | 9206 Expression* callee = expr->expression(); |
| 9186 int argument_count = expr->arguments()->length() + 1; // Plus receiver. | 9207 int argument_count = expr->arguments()->length() + 1; // Plus receiver. |
| 9187 HInstruction* call = NULL; | 9208 HInstruction* call = NULL; |
| 9188 | 9209 |
| 9189 Property* prop = callee->AsProperty(); | 9210 Property* prop = callee->AsProperty(); |
| 9190 if (prop != NULL) { | 9211 if (prop != NULL) { |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 9207 if (!prop->key()->IsPropertyName()) { | 9228 if (!prop->key()->IsPropertyName()) { |
| 9208 CHECK_ALIVE(VisitForValue(prop->key())); | 9229 CHECK_ALIVE(VisitForValue(prop->key())); |
| 9209 key = Pop(); | 9230 key = Pop(); |
| 9210 } | 9231 } |
| 9211 | 9232 |
| 9212 CHECK_ALIVE(PushLoad(prop, receiver, key)); | 9233 CHECK_ALIVE(PushLoad(prop, receiver, key)); |
| 9213 HValue* function = Pop(); | 9234 HValue* function = Pop(); |
| 9214 | 9235 |
| 9215 if (FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); | 9236 if (FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); |
| 9216 | 9237 |
| 9217 // Push the function under the receiver. | |
| 9218 environment()->SetExpressionStackAt(0, function); | |
| 9219 | 9238 |
| 9220 Push(receiver); | |
| 9221 | 9239 |
| 9222 if (function->IsConstant() && | 9240 if (function->IsConstant() && |
| 9223 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { | 9241 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { |
| 9242 // Push the function under the receiver. | |
| 9243 environment()->SetExpressionStackAt(0, function); | |
| 9244 Push(receiver); | |
| 9245 | |
| 9224 Handle<JSFunction> known_function = Handle<JSFunction>::cast( | 9246 Handle<JSFunction> known_function = Handle<JSFunction>::cast( |
| 9225 HConstant::cast(function)->handle(isolate())); | 9247 HConstant::cast(function)->handle(isolate())); |
| 9226 expr->set_target(known_function); | 9248 expr->set_target(known_function); |
| 9227 | 9249 |
| 9228 if (TryIndirectCall(expr)) return; | 9250 if (TryIndirectCall(expr)) return; |
| 9229 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 9251 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
| 9230 | 9252 |
| 9231 Handle<Map> map = types->length() == 1 ? types->first() : Handle<Map>(); | 9253 Handle<Map> map = types->length() == 1 ? types->first() : Handle<Map>(); |
| 9232 if (TryInlineBuiltinMethodCall(expr, known_function, map, | 9254 if (TryInlineBuiltinMethodCall(expr, known_function, map, |
| 9233 expr->arguments()->length())) { | 9255 expr->arguments()->length())) { |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 9249 // HWrapReceiver. | 9271 // HWrapReceiver. |
| 9250 call = New<HCallFunction>( | 9272 call = New<HCallFunction>( |
| 9251 function, argument_count, WRAP_AND_CALL); | 9273 function, argument_count, WRAP_AND_CALL); |
| 9252 } else if (TryInlineCall(expr)) { | 9274 } else if (TryInlineCall(expr)) { |
| 9253 return; | 9275 return; |
| 9254 } else { | 9276 } else { |
| 9255 call = BuildCallConstantFunction(known_function, argument_count); | 9277 call = BuildCallConstantFunction(known_function, argument_count); |
| 9256 } | 9278 } |
| 9257 | 9279 |
| 9258 } else { | 9280 } else { |
| 9259 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 9281 ArgumentsAllowedFlag arguments_flag = ARGUMENTS_NOT_ALLOWED; |
| 9282 if (CanBeFunctionApplyArguments(expr, false)) { | |
|
Jakob Kummerow
2014/11/19 20:46:16
I'm not too happy with this condition. It lacks a
Jakob Kummerow
2014/11/20 09:59:15
I've talked to mvstanton@, he suggested to impleme
ulan
2014/11/20 15:23:29
Done.
ulan
2014/11/20 15:23:29
Acknowledged.
| |
| 9283 Add<HDeoptimize>("Insufficient type feedback for call with arguments", | |
| 9284 Deoptimizer::EAGER); | |
|
Jakob Kummerow
2014/11/19 20:46:16
If we find an appropriate check for "no type feedb
ulan
2014/11/20 15:23:29
Done.
| |
| 9285 arguments_flag = ARGUMENTS_FAKED; | |
| 9286 } | |
| 9287 | |
| 9288 // Push the function under the receiver. | |
| 9289 environment()->SetExpressionStackAt(0, function); | |
| 9290 Push(receiver); | |
| 9291 | |
| 9292 CHECK_ALIVE(VisitExpressions(expr->arguments(), arguments_flag)); | |
| 9260 CallFunctionFlags flags = receiver->type().IsJSObject() | 9293 CallFunctionFlags flags = receiver->type().IsJSObject() |
| 9261 ? NO_CALL_FUNCTION_FLAGS : CALL_AS_METHOD; | 9294 ? NO_CALL_FUNCTION_FLAGS : CALL_AS_METHOD; |
| 9262 call = New<HCallFunction>(function, argument_count, flags); | 9295 call = New<HCallFunction>(function, argument_count, flags); |
| 9263 } | 9296 } |
| 9264 PushArgumentsFromEnvironment(argument_count); | 9297 PushArgumentsFromEnvironment(argument_count); |
| 9265 | 9298 |
| 9266 } else { | 9299 } else { |
| 9267 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 9300 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
| 9268 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { | 9301 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { |
| 9269 return Bailout(kPossibleDirectCallToEval); | 9302 return Bailout(kPossibleDirectCallToEval); |
| (...skipping 3487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 12757 if (ShouldProduceTraceOutput()) { | 12790 if (ShouldProduceTraceOutput()) { |
| 12758 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 12791 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 12759 } | 12792 } |
| 12760 | 12793 |
| 12761 #ifdef DEBUG | 12794 #ifdef DEBUG |
| 12762 graph_->Verify(false); // No full verify. | 12795 graph_->Verify(false); // No full verify. |
| 12763 #endif | 12796 #endif |
| 12764 } | 12797 } |
| 12765 | 12798 |
| 12766 } } // namespace v8::internal | 12799 } } // namespace v8::internal |
| OLD | NEW |