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 |