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 <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "src/v8.h" | 9 #include "src/v8.h" |
10 #include "src/allocation-site-scopes.h" | 10 #include "src/allocation-site-scopes.h" |
(...skipping 4155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4166 | 4166 |
4167 | 4167 |
4168 void HOptimizedGraphBuilder::VisitExpressions( | 4168 void HOptimizedGraphBuilder::VisitExpressions( |
4169 ZoneList<Expression*>* exprs) { | 4169 ZoneList<Expression*>* exprs) { |
4170 for (int i = 0; i < exprs->length(); ++i) { | 4170 for (int i = 0; i < exprs->length(); ++i) { |
4171 CHECK_ALIVE(VisitForValue(exprs->at(i))); | 4171 CHECK_ALIVE(VisitForValue(exprs->at(i))); |
4172 } | 4172 } |
4173 } | 4173 } |
4174 | 4174 |
4175 | 4175 |
| 4176 void HOptimizedGraphBuilder::VisitCallArguments(ZoneList<Expression*>* args, |
| 4177 HValue* function, |
| 4178 bool* args_contain_arguments) { |
| 4179 Handle<JSFunction> known_function; |
| 4180 ArgumentsAllowedFlag is_arguments_allowed = ARGUMENTS_NOT_ALLOWED; |
| 4181 if (function->IsConstant() && |
| 4182 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { |
| 4183 known_function = Handle<JSFunction>::cast( |
| 4184 HConstant::cast(function)->handle(isolate())); |
| 4185 |
| 4186 if (known_function->shared()->CanHandleArgumentsSafely()) { |
| 4187 ASSERT(known_function->shared()->HasBuiltinFunctionId()); |
| 4188 is_arguments_allowed = ARGUMENTS_ALLOWED; |
| 4189 } |
| 4190 } |
| 4191 |
| 4192 bool found_arguments = false; |
| 4193 for (int i = 0; i < args->length(); i++) { |
| 4194 CHECK_ALIVE(VisitForValue(args->at(i), is_arguments_allowed)); |
| 4195 if (!found_arguments) |
| 4196 found_arguments = Top()->CheckFlag(HValue::kIsArguments); |
| 4197 } |
| 4198 *args_contain_arguments = found_arguments; |
| 4199 if (found_arguments) ASSERT(is_arguments_allowed == ARGUMENTS_ALLOWED); |
| 4200 } |
| 4201 |
| 4202 |
4176 bool HOptimizedGraphBuilder::BuildGraph() { | 4203 bool HOptimizedGraphBuilder::BuildGraph() { |
4177 if (current_info()->function()->is_generator()) { | 4204 if (current_info()->function()->is_generator()) { |
4178 Bailout(kFunctionIsAGenerator); | 4205 Bailout(kFunctionIsAGenerator); |
4179 return false; | 4206 return false; |
4180 } | 4207 } |
4181 Scope* scope = current_info()->scope(); | 4208 Scope* scope = current_info()->scope(); |
4182 if (scope->HasIllegalRedeclaration()) { | 4209 if (scope->HasIllegalRedeclaration()) { |
4183 Bailout(kFunctionWithIllegalRedeclaration); | 4210 Bailout(kFunctionWithIllegalRedeclaration); |
4184 return false; | 4211 return false; |
4185 } | 4212 } |
(...skipping 4174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8360 return true; | 8387 return true; |
8361 } | 8388 } |
8362 default: | 8389 default: |
8363 // Not yet supported for inlining. | 8390 // Not yet supported for inlining. |
8364 break; | 8391 break; |
8365 } | 8392 } |
8366 return false; | 8393 return false; |
8367 } | 8394 } |
8368 | 8395 |
8369 | 8396 |
| 8397 void HOptimizedGraphBuilder::InlineBuiltinWithArguments( |
| 8398 Call* expr, |
| 8399 HValue* function, |
| 8400 Handle<Map> receiver_map, |
| 8401 int args_count_no_receiver) { |
| 8402 ASSERT(function->IsConstant() && |
| 8403 HConstant::cast(function)->handle(isolate())->IsJSFunction()); |
| 8404 Handle<JSFunction> known_function = Handle<JSFunction>::cast( |
| 8405 HConstant::cast(function)->handle(isolate())); |
| 8406 ASSERT(known_function->shared()->CanHandleArgumentsSafely()); |
| 8407 ASSERT(known_function->shared()->HasBuiltinFunctionId()); |
| 8408 if (TryInlineBuiltinMethodCall(expr, known_function, receiver_map, |
| 8409 args_count_no_receiver)) { |
| 8410 if (FLAG_trace_inlining) { |
| 8411 PrintF("Inlining builtin "); |
| 8412 known_function->ShortPrint(); |
| 8413 PrintF("\n"); |
| 8414 } |
| 8415 } else { |
| 8416 Bailout(kBadValueContextForArgumentsValue); |
| 8417 } |
| 8418 } |
| 8419 |
| 8420 |
8370 bool HOptimizedGraphBuilder::TryInlineApiFunctionCall(Call* expr, | 8421 bool HOptimizedGraphBuilder::TryInlineApiFunctionCall(Call* expr, |
8371 HValue* receiver) { | 8422 HValue* receiver) { |
8372 Handle<JSFunction> function = expr->target(); | 8423 Handle<JSFunction> function = expr->target(); |
8373 int argc = expr->arguments()->length(); | 8424 int argc = expr->arguments()->length(); |
8374 SmallMapList receiver_maps; | 8425 SmallMapList receiver_maps; |
8375 return TryInlineApiCall(function, | 8426 return TryInlineApiCall(function, |
8376 receiver, | 8427 receiver, |
8377 &receiver_maps, | 8428 &receiver_maps, |
8378 argc, | 8429 argc, |
8379 expr->id(), | 8430 expr->id(), |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8653 | 8704 |
8654 | 8705 |
8655 // f.call(...) | 8706 // f.call(...) |
8656 void HOptimizedGraphBuilder::BuildFunctionCall(Call* expr) { | 8707 void HOptimizedGraphBuilder::BuildFunctionCall(Call* expr) { |
8657 HValue* function = Pop(); // f | 8708 HValue* function = Pop(); // f |
8658 HValue* receiver; | 8709 HValue* receiver; |
8659 ZoneList<Expression*>* args = expr->arguments(); | 8710 ZoneList<Expression*>* args = expr->arguments(); |
8660 int args_length = args->length(); | 8711 int args_length = args->length(); |
8661 Drop(1); // call | 8712 Drop(1); // call |
8662 | 8713 |
| 8714 Push(function); |
| 8715 bool have_arguments = false; |
8663 if (args_length == 0) { | 8716 if (args_length == 0) { |
8664 receiver = graph()->GetConstantUndefined(); | 8717 receiver = BuildWrapReceiver(graph()->GetConstantUndefined(), function); |
8665 args_length = 1; | 8718 args_length = 1; |
| 8719 Push(receiver); |
8666 } else { | 8720 } else { |
8667 CHECK_ALIVE(VisitForValue(args->at(0))); | 8721 CHECK_ALIVE(VisitCallArguments(args, function, &have_arguments)); |
8668 receiver = Pop(); | 8722 receiver = BuildWrapReceiver( |
| 8723 environment()->ExpressionStackAt(args_length - 1), function); |
| 8724 environment()->SetExpressionStackAt(args_length - 1, receiver); |
8669 } | 8725 } |
8670 receiver = BuildWrapReceiver(receiver, function); | |
8671 | 8726 |
8672 Push(function); | 8727 if (have_arguments) { |
8673 Push(receiver); | 8728 Handle<Map> map; |
8674 for (int i = 1; i < args_length; i++) { | 8729 CHECK_BAILOUT(InlineBuiltinWithArguments(expr, function, map, |
8675 CHECK_ALIVE(VisitForValue(args->at(i))); | 8730 args_length - 1)); |
8676 } | 8731 } |
| 8732 ASSERT(!have_arguments); |
8677 HandleIndirectCall(expr, function, args_length); | 8733 HandleIndirectCall(expr, function, args_length); |
8678 } | 8734 } |
8679 | 8735 |
8680 | 8736 |
8681 HValue* HOptimizedGraphBuilder::ImplicitReceiverFor(HValue* function, | 8737 HValue* HOptimizedGraphBuilder::ImplicitReceiverFor(HValue* function, |
8682 Handle<JSFunction> target) { | 8738 Handle<JSFunction> target) { |
8683 SharedFunctionInfo* shared = target->shared(); | 8739 SharedFunctionInfo* shared = target->shared(); |
8684 if (shared->strict_mode() == SLOPPY && !shared->native()) { | 8740 if (shared->strict_mode() == SLOPPY && !shared->native()) { |
8685 // Cannot embed a direct reference to the global proxy | 8741 // Cannot embed a direct reference to the global proxy |
8686 // as is it dropped on deserialization. | 8742 // as is it dropped on deserialization. |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8933 | 8989 |
8934 Push(receiver); | 8990 Push(receiver); |
8935 | 8991 |
8936 if (function->IsConstant() && | 8992 if (function->IsConstant() && |
8937 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { | 8993 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { |
8938 Handle<JSFunction> known_function = Handle<JSFunction>::cast( | 8994 Handle<JSFunction> known_function = Handle<JSFunction>::cast( |
8939 HConstant::cast(function)->handle(isolate())); | 8995 HConstant::cast(function)->handle(isolate())); |
8940 expr->set_target(known_function); | 8996 expr->set_target(known_function); |
8941 | 8997 |
8942 if (TryIndirectCall(expr)) return; | 8998 if (TryIndirectCall(expr)) return; |
8943 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 8999 bool have_arguments = false; |
| 9000 CHECK_ALIVE(VisitCallArguments(expr->arguments(), function, |
| 9001 &have_arguments)); |
8944 | 9002 |
8945 Handle<Map> map = types->length() == 1 ? types->first() : Handle<Map>(); | 9003 Handle<Map> map = types->length() == 1 ? types->first() : Handle<Map>(); |
| 9004 if (have_arguments) { |
| 9005 CHECK_BAILOUT(InlineBuiltinWithArguments(expr, |
| 9006 function, |
| 9007 map, |
| 9008 expr->arguments()->length())); |
| 9009 } |
| 9010 ASSERT(!have_arguments); |
8946 if (TryInlineBuiltinMethodCall(expr, known_function, map, | 9011 if (TryInlineBuiltinMethodCall(expr, known_function, map, |
8947 expr->arguments()->length())) { | 9012 expr->arguments()->length())) { |
8948 if (FLAG_trace_inlining) { | 9013 if (FLAG_trace_inlining) { |
8949 PrintF("Inlining builtin "); | 9014 PrintF("Inlining builtin "); |
8950 known_function->ShortPrint(); | 9015 known_function->ShortPrint(); |
8951 PrintF("\n"); | 9016 PrintF("\n"); |
8952 } | 9017 } |
8953 return; | 9018 return; |
8954 } | 9019 } |
8955 if (TryInlineApiMethodCall(expr, receiver, types)) return; | 9020 if (TryInlineApiMethodCall(expr, receiver, types)) return; |
(...skipping 3461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12417 if (ShouldProduceTraceOutput()) { | 12482 if (ShouldProduceTraceOutput()) { |
12418 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 12483 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
12419 } | 12484 } |
12420 | 12485 |
12421 #ifdef DEBUG | 12486 #ifdef DEBUG |
12422 graph_->Verify(false); // No full verify. | 12487 graph_->Verify(false); // No full verify. |
12423 #endif | 12488 #endif |
12424 } | 12489 } |
12425 | 12490 |
12426 } } // namespace v8::internal | 12491 } } // namespace v8::internal |
OLD | NEW |