| 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)) 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(Call* expr) { |
| 9189 ZoneList<Expression*>* args = expr->arguments(); |
| 9190 if (args->length() != 2) return false; |
| 9191 VariableProxy* arg_two = args->at(1)->AsVariableProxy(); |
| 9192 if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false; |
| 9193 HValue* arg_two_value = LookupAndMakeLive(arg_two->var()); |
| 9194 if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false; |
| 9195 return true; |
| 9196 } |
| 9197 |
| 9198 |
| 9181 void HOptimizedGraphBuilder::VisitCall(Call* expr) { | 9199 void HOptimizedGraphBuilder::VisitCall(Call* expr) { |
| 9182 DCHECK(!HasStackOverflow()); | 9200 DCHECK(!HasStackOverflow()); |
| 9183 DCHECK(current_block() != NULL); | 9201 DCHECK(current_block() != NULL); |
| 9184 DCHECK(current_block()->HasPredecessor()); | 9202 DCHECK(current_block()->HasPredecessor()); |
| 9185 Expression* callee = expr->expression(); | 9203 Expression* callee = expr->expression(); |
| 9186 int argument_count = expr->arguments()->length() + 1; // Plus receiver. | 9204 int argument_count = expr->arguments()->length() + 1; // Plus receiver. |
| 9187 HInstruction* call = NULL; | 9205 HInstruction* call = NULL; |
| 9188 | 9206 |
| 9189 Property* prop = callee->AsProperty(); | 9207 Property* prop = callee->AsProperty(); |
| 9190 if (prop != NULL) { | 9208 if (prop != NULL) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 9207 if (!prop->key()->IsPropertyName()) { | 9225 if (!prop->key()->IsPropertyName()) { |
| 9208 CHECK_ALIVE(VisitForValue(prop->key())); | 9226 CHECK_ALIVE(VisitForValue(prop->key())); |
| 9209 key = Pop(); | 9227 key = Pop(); |
| 9210 } | 9228 } |
| 9211 | 9229 |
| 9212 CHECK_ALIVE(PushLoad(prop, receiver, key)); | 9230 CHECK_ALIVE(PushLoad(prop, receiver, key)); |
| 9213 HValue* function = Pop(); | 9231 HValue* function = Pop(); |
| 9214 | 9232 |
| 9215 if (FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); | 9233 if (FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); |
| 9216 | 9234 |
| 9217 // Push the function under the receiver. | |
| 9218 environment()->SetExpressionStackAt(0, function); | |
| 9219 | 9235 |
| 9220 Push(receiver); | |
| 9221 | 9236 |
| 9222 if (function->IsConstant() && | 9237 if (function->IsConstant() && |
| 9223 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { | 9238 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { |
| 9239 // Push the function under the receiver. |
| 9240 environment()->SetExpressionStackAt(0, function); |
| 9241 Push(receiver); |
| 9242 |
| 9224 Handle<JSFunction> known_function = Handle<JSFunction>::cast( | 9243 Handle<JSFunction> known_function = Handle<JSFunction>::cast( |
| 9225 HConstant::cast(function)->handle(isolate())); | 9244 HConstant::cast(function)->handle(isolate())); |
| 9226 expr->set_target(known_function); | 9245 expr->set_target(known_function); |
| 9227 | 9246 |
| 9228 if (TryIndirectCall(expr)) return; | 9247 if (TryIndirectCall(expr)) return; |
| 9229 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 9248 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
| 9230 | 9249 |
| 9231 Handle<Map> map = types->length() == 1 ? types->first() : Handle<Map>(); | 9250 Handle<Map> map = types->length() == 1 ? types->first() : Handle<Map>(); |
| 9232 if (TryInlineBuiltinMethodCall(expr, known_function, map, | 9251 if (TryInlineBuiltinMethodCall(expr, known_function, map, |
| 9233 expr->arguments()->length())) { | 9252 expr->arguments()->length())) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 9249 // HWrapReceiver. | 9268 // HWrapReceiver. |
| 9250 call = New<HCallFunction>( | 9269 call = New<HCallFunction>( |
| 9251 function, argument_count, WRAP_AND_CALL); | 9270 function, argument_count, WRAP_AND_CALL); |
| 9252 } else if (TryInlineCall(expr)) { | 9271 } else if (TryInlineCall(expr)) { |
| 9253 return; | 9272 return; |
| 9254 } else { | 9273 } else { |
| 9255 call = BuildCallConstantFunction(known_function, argument_count); | 9274 call = BuildCallConstantFunction(known_function, argument_count); |
| 9256 } | 9275 } |
| 9257 | 9276 |
| 9258 } else { | 9277 } else { |
| 9259 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 9278 ArgumentsAllowedFlag arguments_flag = ARGUMENTS_NOT_ALLOWED; |
| 9279 if (CanBeFunctionApplyArguments(expr) && expr->is_uninitialized()) { |
| 9280 // We have to use EAGER deoptimization here because Deoptimizer::SOFT |
| 9281 // gets ignored by the always-opt flag, which leads to incorrect code. |
| 9282 Add<HDeoptimize>("Insufficient type feedback for call with arguments", |
| 9283 Deoptimizer::EAGER); |
| 9284 arguments_flag = ARGUMENTS_FAKED; |
| 9285 } |
| 9286 |
| 9287 // Push the function under the receiver. |
| 9288 environment()->SetExpressionStackAt(0, function); |
| 9289 Push(receiver); |
| 9290 |
| 9291 CHECK_ALIVE(VisitExpressions(expr->arguments(), arguments_flag)); |
| 9260 CallFunctionFlags flags = receiver->type().IsJSObject() | 9292 CallFunctionFlags flags = receiver->type().IsJSObject() |
| 9261 ? NO_CALL_FUNCTION_FLAGS : CALL_AS_METHOD; | 9293 ? NO_CALL_FUNCTION_FLAGS : CALL_AS_METHOD; |
| 9262 call = New<HCallFunction>(function, argument_count, flags); | 9294 call = New<HCallFunction>(function, argument_count, flags); |
| 9263 } | 9295 } |
| 9264 PushArgumentsFromEnvironment(argument_count); | 9296 PushArgumentsFromEnvironment(argument_count); |
| 9265 | 9297 |
| 9266 } else { | 9298 } else { |
| 9267 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 9299 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
| 9268 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { | 9300 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { |
| 9269 return Bailout(kPossibleDirectCallToEval); | 9301 return Bailout(kPossibleDirectCallToEval); |
| (...skipping 3487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12757 if (ShouldProduceTraceOutput()) { | 12789 if (ShouldProduceTraceOutput()) { |
| 12758 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 12790 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 12759 } | 12791 } |
| 12760 | 12792 |
| 12761 #ifdef DEBUG | 12793 #ifdef DEBUG |
| 12762 graph_->Verify(false); // No full verify. | 12794 graph_->Verify(false); // No full verify. |
| 12763 #endif | 12795 #endif |
| 12764 } | 12796 } |
| 12765 | 12797 |
| 12766 } } // namespace v8::internal | 12798 } } // namespace v8::internal |
| OLD | NEW |