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 <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 7957 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7968 } | 7968 } |
| 7969 break; | 7969 break; |
| 7970 default: | 7970 default: |
| 7971 // Not supported for inlining yet. | 7971 // Not supported for inlining yet. |
| 7972 break; | 7972 break; |
| 7973 } | 7973 } |
| 7974 return false; | 7974 return false; |
| 7975 } | 7975 } |
| 7976 | 7976 |
| 7977 | 7977 |
| 7978 bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall( | 7978 bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall( |
|
Toon Verwaest
2014/06/12 21:41:13
Does it make sense to have both methods? I'm prett
p.antonov
2014/06/13 08:34:24
Done.
| |
| 7979 Call* expr, | 7979 Call* expr, |
| 7980 HValue* receiver, | 7980 HValue* receiver, |
| 7981 Handle<Map> receiver_map) { | 7981 Handle<Map> map, |
| 7982 Handle<JSFunction> function, | |
| 7983 int args_count_no_receiver | |
| 7984 ) { | |
|
Toon Verwaest
2014/06/12 21:41:13
Nit: put ) { back on the previous line
p.antonov
2014/06/13 08:34:24
Done.
| |
| 7985 if (!function->shared()->HasBuiltinFunctionId()) return false; | |
| 7986 BuiltinFunctionId id = function->shared()->builtin_function_id(); | |
| 7987 if (InlineBuiltinMethodCall(expr, receiver, map, id, | |
| 7988 args_count_no_receiver)) { | |
| 7989 if (FLAG_trace_inlining) { | |
| 7990 PrintF("Inlining builtin "); | |
| 7991 function->ShortPrint(); | |
| 7992 PrintF("\n"); | |
| 7993 } | |
| 7994 return true; | |
| 7995 } | |
| 7996 return false; | |
| 7997 } | |
| 7998 | |
| 7999 | |
| 8000 bool HOptimizedGraphBuilder::InlineBuiltinMethodCall( | |
| 8001 Call* expr, | |
| 8002 HValue* receiver, | |
| 8003 Handle<Map> receiver_map, | |
| 8004 BuiltinFunctionId id, | |
| 8005 // expr could be .call or .apply so it's not safe to rely on its | |
|
Toon Verwaest
2014/06/12 21:41:13
I don't think we need this comment...
p.antonov
2014/06/13 08:34:24
Done.
| |
| 8006 // ->arguments()->length() | |
| 8007 int args_count_no_receiver) { | |
| 8008 int argument_count = args_count_no_receiver + 1; // Plus receiver. | |
| 7982 // Try to inline calls like Math.* as operations in the calling function. | 8009 // Try to inline calls like Math.* as operations in the calling function. |
| 7983 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; | |
| 7984 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); | |
| 7985 int argument_count = expr->arguments()->length() + 1; // Plus receiver. | |
| 7986 switch (id) { | 8010 switch (id) { |
| 7987 case kStringCharCodeAt: | 8011 case kStringCharCodeAt: |
| 7988 case kStringCharAt: | 8012 case kStringCharAt: |
| 7989 if (argument_count == 2) { | 8013 if (argument_count == 2) { |
| 7990 HValue* index = Pop(); | 8014 HValue* index = Pop(); |
| 7991 HValue* string = Pop(); | 8015 HValue* string = Pop(); |
| 7992 Drop(1); // Function. | 8016 Drop(1); // Function. |
| 7993 HInstruction* char_code = | 8017 HInstruction* char_code = |
| 7994 BuildStringCharCodeAt(string, index); | 8018 BuildStringCharCodeAt(string, index); |
| 7995 if (id == kStringCharCodeAt) { | 8019 if (id == kStringCharCodeAt) { |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8083 } | 8107 } |
| 8084 break; | 8108 break; |
| 8085 case kArrayPop: { | 8109 case kArrayPop: { |
| 8086 if (receiver_map.is_null()) return false; | 8110 if (receiver_map.is_null()) return false; |
| 8087 if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false; | 8111 if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false; |
| 8088 ElementsKind elements_kind = receiver_map->elements_kind(); | 8112 ElementsKind elements_kind = receiver_map->elements_kind(); |
| 8089 if (!IsFastElementsKind(elements_kind)) return false; | 8113 if (!IsFastElementsKind(elements_kind)) return false; |
| 8090 if (receiver_map->is_observed()) return false; | 8114 if (receiver_map->is_observed()) return false; |
| 8091 ASSERT(receiver_map->is_extensible()); | 8115 ASSERT(receiver_map->is_extensible()); |
| 8092 | 8116 |
| 8093 Drop(expr->arguments()->length()); | 8117 Drop(args_count_no_receiver); |
| 8094 HValue* result; | 8118 HValue* result; |
| 8095 HValue* reduced_length; | 8119 HValue* reduced_length; |
| 8096 HValue* receiver = Pop(); | 8120 HValue* receiver = Pop(); |
| 8097 | 8121 |
| 8098 HValue* checked_object = AddCheckMap(receiver, receiver_map); | 8122 HValue* checked_object = AddCheckMap(receiver, receiver_map); |
| 8099 HValue* length = Add<HLoadNamedField>( | 8123 HValue* length = Add<HLoadNamedField>( |
| 8100 checked_object, static_cast<HValue*>(NULL), | 8124 checked_object, static_cast<HValue*>(NULL), |
| 8101 HObjectAccess::ForArrayLength(elements_kind)); | 8125 HObjectAccess::ForArrayLength(elements_kind)); |
| 8102 | 8126 |
| 8103 Drop(1); // Function. | 8127 Drop(1); // Function. |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8159 // inlined version can't be used. | 8183 // inlined version can't be used. |
| 8160 if (receiver_map->DictionaryElementsInPrototypeChainOnly()) return false; | 8184 if (receiver_map->DictionaryElementsInPrototypeChainOnly()) return false; |
| 8161 // If there currently can be no elements accessors on the prototype chain, | 8185 // If there currently can be no elements accessors on the prototype chain, |
| 8162 // it doesn't mean that there won't be any later. Install a full prototype | 8186 // it doesn't mean that there won't be any later. Install a full prototype |
| 8163 // chain check to trap element accessors being installed on the prototype | 8187 // chain check to trap element accessors being installed on the prototype |
| 8164 // chain, which would cause elements to go to dictionary mode and result | 8188 // chain, which would cause elements to go to dictionary mode and result |
| 8165 // in a map change. | 8189 // in a map change. |
| 8166 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype())); | 8190 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype())); |
| 8167 BuildCheckPrototypeMaps(prototype, Handle<JSObject>()); | 8191 BuildCheckPrototypeMaps(prototype, Handle<JSObject>()); |
| 8168 | 8192 |
| 8169 const int argc = expr->arguments()->length(); | 8193 const int argc = args_count_no_receiver; |
| 8170 if (argc != 1) return false; | 8194 if (argc != 1) return false; |
| 8171 | 8195 |
| 8172 HValue* value_to_push = Pop(); | 8196 HValue* value_to_push = Pop(); |
| 8173 HValue* array = Pop(); | 8197 HValue* array = Pop(); |
| 8174 Drop(1); // Drop function. | 8198 Drop(1); // Drop function. |
| 8175 | 8199 |
| 8176 HInstruction* new_size = NULL; | 8200 HInstruction* new_size = NULL; |
| 8177 HValue* length = NULL; | 8201 HValue* length = NULL; |
| 8178 | 8202 |
| 8179 { | 8203 { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8216 // chain check to trap element accessors being installed on the prototype | 8240 // chain check to trap element accessors being installed on the prototype |
| 8217 // chain, which would cause elements to go to dictionary mode and result | 8241 // chain, which would cause elements to go to dictionary mode and result |
| 8218 // in a map change. | 8242 // in a map change. |
| 8219 BuildCheckPrototypeMaps( | 8243 BuildCheckPrototypeMaps( |
| 8220 handle(JSObject::cast(receiver_map->prototype()), isolate()), | 8244 handle(JSObject::cast(receiver_map->prototype()), isolate()), |
| 8221 Handle<JSObject>::null()); | 8245 Handle<JSObject>::null()); |
| 8222 | 8246 |
| 8223 // Threshold for fast inlined Array.shift(). | 8247 // Threshold for fast inlined Array.shift(). |
| 8224 HConstant* inline_threshold = Add<HConstant>(static_cast<int32_t>(16)); | 8248 HConstant* inline_threshold = Add<HConstant>(static_cast<int32_t>(16)); |
| 8225 | 8249 |
| 8226 Drop(expr->arguments()->length()); | 8250 Drop(args_count_no_receiver); |
| 8227 HValue* receiver = Pop(); | 8251 HValue* receiver = Pop(); |
| 8228 HValue* function = Pop(); | 8252 HValue* function = Pop(); |
| 8229 HValue* result; | 8253 HValue* result; |
| 8230 | 8254 |
| 8231 { | 8255 { |
| 8232 NoObservableSideEffectsScope scope(this); | 8256 NoObservableSideEffectsScope scope(this); |
| 8233 | 8257 |
| 8234 HValue* length = Add<HLoadNamedField>( | 8258 HValue* length = Add<HLoadNamedField>( |
| 8235 receiver, static_cast<HValue*>(NULL), | 8259 receiver, static_cast<HValue*>(NULL), |
| 8236 HObjectAccess::ForArrayLength(kind)); | 8260 HObjectAccess::ForArrayLength(kind)); |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8527 HInstruction* call = New<HCallWithDescriptor>( | 8551 HInstruction* call = New<HCallWithDescriptor>( |
| 8528 code_value, argc + 1, descriptor, | 8552 code_value, argc + 1, descriptor, |
| 8529 Vector<HValue*>(op_vals, descriptor->environment_length())); | 8553 Vector<HValue*>(op_vals, descriptor->environment_length())); |
| 8530 | 8554 |
| 8531 if (drop_extra) Drop(1); // Drop function. | 8555 if (drop_extra) Drop(1); // Drop function. |
| 8532 ast_context()->ReturnInstruction(call, ast_id); | 8556 ast_context()->ReturnInstruction(call, ast_id); |
| 8533 return true; | 8557 return true; |
| 8534 } | 8558 } |
| 8535 | 8559 |
| 8536 | 8560 |
| 8537 bool HOptimizedGraphBuilder::TryCallApply(Call* expr) { | 8561 void HOptimizedGraphBuilder::HandleIndirectCall(Call* expr, |
| 8562 HValue* function, | |
| 8563 int arguments_count) { | |
| 8564 Handle<JSFunction> known_function; | |
| 8565 int args_count_no_receiver = arguments_count - 1; | |
| 8566 if (function->IsConstant() && | |
| 8567 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { | |
| 8568 known_function = Handle<JSFunction>::cast( | |
| 8569 HConstant::cast(function)->handle(isolate())); | |
| 8570 if (TryInlineApply(known_function, expr, args_count_no_receiver)) { | |
|
Toon Verwaest
2014/06/12 21:41:13
Seems like TryIndirectCall splits to apply and cal
p.antonov
2014/06/13 08:34:24
Done.
| |
| 8571 return; | |
| 8572 } | |
| 8573 | |
| 8574 Handle<Map> map; | |
| 8575 HValue* receiver = environment()->ExpressionStackAt(args_count_no_receiver); | |
|
Toon Verwaest
2014/06/12 21:41:13
Can you move this code into TryInlineBuiltinMethod
p.antonov
2014/06/13 08:34:24
Done.
| |
| 8576 if (receiver->IsConstant() && | |
| 8577 HConstant::cast(receiver)->handle(isolate())->IsHeapObject()) { | |
| 8578 map = handle(Handle<HeapObject>::cast( | |
| 8579 HConstant::cast(receiver)->handle(isolate()))->map()); | |
| 8580 } | |
| 8581 if (TryInlineBuiltinMethodCall(expr, receiver, map, known_function, | |
|
Toon Verwaest
2014/06/12 21:41:13
This was already done in BuildFunctionCallCall. Ca
p.antonov
2014/06/13 08:34:24
Done.
| |
| 8582 args_count_no_receiver)) { | |
| 8583 return; | |
| 8584 } | |
| 8585 } | |
| 8586 | |
| 8587 PushArgumentsFromEnvironment(arguments_count); | |
| 8588 HInvokeFunction* call = New<HInvokeFunction>( | |
| 8589 function, known_function, arguments_count); | |
| 8590 Drop(1); // Function | |
| 8591 ast_context()->ReturnInstruction(call, expr->id()); | |
| 8592 } | |
| 8593 | |
| 8594 | |
| 8595 bool HOptimizedGraphBuilder::TryIndirectCall(Call* expr) { | |
| 8538 ASSERT(expr->expression()->IsProperty()); | 8596 ASSERT(expr->expression()->IsProperty()); |
| 8539 | 8597 |
| 8540 if (!expr->IsMonomorphic()) { | 8598 if (!expr->IsMonomorphic()) { |
| 8541 return false; | 8599 return false; |
| 8542 } | 8600 } |
| 8543 Handle<Map> function_map = expr->GetReceiverTypes()->first(); | 8601 Handle<Map> function_map = expr->GetReceiverTypes()->first(); |
| 8544 if (function_map->instance_type() != JS_FUNCTION_TYPE || | 8602 if (function_map->instance_type() != JS_FUNCTION_TYPE || |
| 8545 !expr->target()->shared()->HasBuiltinFunctionId() || | 8603 !expr->target()->shared()->HasBuiltinFunctionId()) { |
|
Toon Verwaest
2014/06/12 21:41:13
What about creating both BuildFunctionCall and Bui
p.antonov
2014/06/13 08:34:24
Done.
| |
| 8546 expr->target()->shared()->builtin_function_id() != kFunctionApply) { | 8604 return false; |
| 8605 } | |
| 8606 if (expr->target()->shared()->builtin_function_id() == kFunctionCall) { | |
| 8607 BuildFunctionCallCall(expr); | |
| 8608 return true; | |
| 8609 } | |
| 8610 if (expr->target()->shared()->builtin_function_id() != kFunctionApply) { | |
| 8547 return false; | 8611 return false; |
| 8548 } | 8612 } |
| 8549 | 8613 |
| 8550 if (current_info()->scope()->arguments() == NULL) return false; | 8614 if (current_info()->scope()->arguments() == NULL) return false; |
| 8551 | 8615 |
| 8552 ZoneList<Expression*>* args = expr->arguments(); | 8616 ZoneList<Expression*>* args = expr->arguments(); |
| 8553 if (args->length() != 2) return false; | 8617 if (args->length() != 2) return false; |
| 8554 | 8618 |
| 8555 VariableProxy* arg_two = args->at(1)->AsVariableProxy(); | 8619 VariableProxy* arg_two = args->at(1)->AsVariableProxy(); |
| 8556 if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false; | 8620 if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false; |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 8579 ASSERT_EQ(environment()->arguments_environment()->parameter_count(), | 8643 ASSERT_EQ(environment()->arguments_environment()->parameter_count(), |
| 8580 function_state()->entry()->arguments_object()->arguments_count()); | 8644 function_state()->entry()->arguments_object()->arguments_count()); |
| 8581 HArgumentsObject* args = function_state()->entry()->arguments_object(); | 8645 HArgumentsObject* args = function_state()->entry()->arguments_object(); |
| 8582 const ZoneList<HValue*>* arguments_values = args->arguments_values(); | 8646 const ZoneList<HValue*>* arguments_values = args->arguments_values(); |
| 8583 int arguments_count = arguments_values->length(); | 8647 int arguments_count = arguments_values->length(); |
| 8584 Push(function); | 8648 Push(function); |
| 8585 Push(BuildWrapReceiver(receiver, function)); | 8649 Push(BuildWrapReceiver(receiver, function)); |
| 8586 for (int i = 1; i < arguments_count; i++) { | 8650 for (int i = 1; i < arguments_count; i++) { |
| 8587 Push(arguments_values->at(i)); | 8651 Push(arguments_values->at(i)); |
| 8588 } | 8652 } |
| 8589 | 8653 HandleIndirectCall(expr, function, arguments_count); |
| 8590 Handle<JSFunction> known_function; | |
| 8591 if (function->IsConstant() && | |
| 8592 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { | |
| 8593 known_function = Handle<JSFunction>::cast( | |
| 8594 HConstant::cast(function)->handle(isolate())); | |
| 8595 int args_count = arguments_count - 1; // Excluding receiver. | |
| 8596 if (TryInlineApply(known_function, expr, args_count)) return true; | |
| 8597 } | |
| 8598 | |
| 8599 PushArgumentsFromEnvironment(arguments_count); | |
| 8600 HInvokeFunction* call = New<HInvokeFunction>( | |
| 8601 function, known_function, arguments_count); | |
| 8602 Drop(1); // Function. | |
| 8603 ast_context()->ReturnInstruction(call, expr->id()); | |
| 8604 return true; | 8654 return true; |
| 8605 } | 8655 } |
| 8606 } | 8656 } |
| 8607 | 8657 |
| 8608 | 8658 |
| 8659 // f.call(...) | |
| 8660 void HOptimizedGraphBuilder::BuildFunctionCallCall(Call* expr) { | |
| 8661 HValue* function = Pop(); // f | |
| 8662 HValue* receiver; | |
| 8663 ZoneList<Expression*>* args = expr->arguments(); | |
| 8664 int args_length = args->length(); | |
| 8665 bool is_builtin_call = false; | |
| 8666 Handle<JSFunction> known_function; | |
| 8667 Drop(1); // call | |
| 8668 | |
| 8669 if (function->IsConstant() && | |
| 8670 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { | |
| 8671 known_function = Handle<JSFunction>::cast( | |
| 8672 HConstant::cast(function)->handle(isolate())); | |
| 8673 is_builtin_call = known_function->shared()->HasBuiltinFunctionId(); | |
| 8674 } | |
| 8675 | |
| 8676 ArgumentsAllowedFlag flag = is_builtin_call | |
| 8677 ? ARGUMENTS_ALLOWED : ARGUMENTS_NOT_ALLOWED; | |
| 8678 | |
| 8679 if (args_length == 0) { | |
| 8680 receiver = graph()->GetConstantUndefined(); | |
| 8681 args_length = 1; | |
| 8682 } else { | |
| 8683 CHECK_ALIVE(VisitForValue(args->at(0), flag)); | |
| 8684 receiver = Pop(); | |
| 8685 } | |
| 8686 receiver = is_builtin_call ? receiver : BuildWrapReceiver(receiver, function); | |
|
Toon Verwaest
2014/06/12 21:41:14
You can't just skip BuildWrapReceiver for builtins
p.antonov
2014/06/13 08:34:24
Done.
| |
| 8687 | |
| 8688 Push(function); | |
| 8689 Push(receiver); | |
| 8690 for (int i = 1; i < args_length; i++) { | |
| 8691 CHECK_ALIVE(VisitForValue(args->at(i), flag)); | |
| 8692 } | |
| 8693 | |
| 8694 if (is_builtin_call) { | |
| 8695 ASSERT(!known_function.is_null()); | |
| 8696 | |
| 8697 Handle<Map> map; | |
| 8698 if (receiver->IsConstant() && | |
| 8699 HConstant::cast(receiver)->handle(isolate())->IsHeapObject()) { | |
| 8700 map = handle(Handle<HeapObject>::cast( | |
| 8701 HConstant::cast(receiver)->handle(isolate()))->map()); | |
| 8702 } | |
| 8703 | |
| 8704 int args_count_no_receiver = args_length - 1; | |
| 8705 if (TryInlineBuiltinMethodCall(expr, receiver, map, known_function, | |
| 8706 args_count_no_receiver)) { | |
| 8707 return; | |
| 8708 } | |
| 8709 // Failing to inline as a builtin means arguments cannot | |
| 8710 // be allowed after all. | |
|
Toon Verwaest
2014/06/12 21:41:13
Iek! So what if I do the following?
a = [];
a.pus
p.antonov
2014/06/13 08:34:24
Done.
| |
| 8711 for (int i = 0; i < args_length; ++i) { | |
| 8712 HValue* arg = environment()->ExpressionStackAt(i); | |
| 8713 if (arg->CheckFlag(HValue::kIsArguments)) { | |
| 8714 return Bailout(kBadValueContextForArgumentsValue); | |
| 8715 } | |
| 8716 } | |
| 8717 } | |
| 8718 HandleIndirectCall(expr, function, args_length); | |
| 8719 } | |
| 8720 | |
| 8721 | |
| 8609 HValue* HOptimizedGraphBuilder::ImplicitReceiverFor(HValue* function, | 8722 HValue* HOptimizedGraphBuilder::ImplicitReceiverFor(HValue* function, |
| 8610 Handle<JSFunction> target) { | 8723 Handle<JSFunction> target) { |
| 8611 SharedFunctionInfo* shared = target->shared(); | 8724 SharedFunctionInfo* shared = target->shared(); |
| 8612 if (shared->strict_mode() == SLOPPY && !shared->native()) { | 8725 if (shared->strict_mode() == SLOPPY && !shared->native()) { |
| 8613 // Cannot embed a direct reference to the global proxy | 8726 // Cannot embed a direct reference to the global proxy |
| 8614 // as is it dropped on deserialization. | 8727 // as is it dropped on deserialization. |
| 8615 CHECK(!isolate()->serializer_enabled()); | 8728 CHECK(!isolate()->serializer_enabled()); |
| 8616 Handle<JSObject> global_receiver( | 8729 Handle<JSObject> global_receiver( |
| 8617 target->context()->global_object()->global_receiver()); | 8730 target->context()->global_object()->global_receiver()); |
| 8618 return Add<HConstant>(global_receiver); | 8731 return Add<HConstant>(global_receiver); |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8860 environment()->SetExpressionStackAt(0, function); | 8973 environment()->SetExpressionStackAt(0, function); |
| 8861 | 8974 |
| 8862 Push(receiver); | 8975 Push(receiver); |
| 8863 | 8976 |
| 8864 if (function->IsConstant() && | 8977 if (function->IsConstant() && |
| 8865 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { | 8978 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { |
| 8866 Handle<JSFunction> known_function = Handle<JSFunction>::cast( | 8979 Handle<JSFunction> known_function = Handle<JSFunction>::cast( |
| 8867 HConstant::cast(function)->handle(isolate())); | 8980 HConstant::cast(function)->handle(isolate())); |
| 8868 expr->set_target(known_function); | 8981 expr->set_target(known_function); |
| 8869 | 8982 |
| 8870 if (TryCallApply(expr)) return; | 8983 if (TryIndirectCall(expr)) return; |
| 8871 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 8984 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
| 8872 | 8985 |
| 8873 Handle<Map> map = types->length() == 1 ? types->first() : Handle<Map>(); | 8986 Handle<Map> map = types->length() == 1 ? types->first() : Handle<Map>(); |
| 8874 if (TryInlineBuiltinMethodCall(expr, receiver, map)) { | 8987 if (TryInlineBuiltinMethodCall(expr, receiver, map, known_function, |
| 8875 if (FLAG_trace_inlining) { | 8988 expr->arguments()->length())) { |
| 8876 PrintF("Inlining builtin "); | |
| 8877 known_function->ShortPrint(); | |
| 8878 PrintF("\n"); | |
| 8879 } | |
| 8880 return; | 8989 return; |
| 8881 } | 8990 } |
| 8882 if (TryInlineApiMethodCall(expr, receiver, types)) return; | 8991 if (TryInlineApiMethodCall(expr, receiver, types)) return; |
| 8883 | 8992 |
| 8884 // Wrap the receiver if necessary. | 8993 // Wrap the receiver if necessary. |
| 8885 if (NeedsWrappingFor(ToType(types->first()), known_function)) { | 8994 if (NeedsWrappingFor(ToType(types->first()), known_function)) { |
| 8886 // Since HWrapReceiver currently cannot actually wrap numbers and | 8995 // Since HWrapReceiver currently cannot actually wrap numbers and |
| 8887 // strings, use the regular CallFunctionStub for method calls to wrap | 8996 // strings, use the regular CallFunctionStub for method calls to wrap |
| 8888 // the receiver. | 8997 // the receiver. |
| 8889 // TODO(verwaest): Support creation of value wrappers directly in | 8998 // TODO(verwaest): Support creation of value wrappers directly in |
| (...skipping 3454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 12344 if (ShouldProduceTraceOutput()) { | 12453 if (ShouldProduceTraceOutput()) { |
| 12345 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 12454 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 12346 } | 12455 } |
| 12347 | 12456 |
| 12348 #ifdef DEBUG | 12457 #ifdef DEBUG |
| 12349 graph_->Verify(false); // No full verify. | 12458 graph_->Verify(false); // No full verify. |
| 12350 #endif | 12459 #endif |
| 12351 } | 12460 } |
| 12352 | 12461 |
| 12353 } } // namespace v8::internal | 12462 } } // namespace v8::internal |
| OLD | NEW |