| 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 |