Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: src/crankshaft/hydrogen.cc

Issue 1731303002: [crankshaft] Remove useless HCallFunction instruction. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/crankshaft/hydrogen.h ('k') | src/crankshaft/hydrogen-instructions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/crankshaft/hydrogen.h" 5 #include "src/crankshaft/hydrogen.h"
6 6
7 #include <sstream> 7 #include <sstream>
8 8
9 #include "src/allocation-site-scopes.h" 9 #include "src/allocation-site-scopes.h"
10 #include "src/ast/ast-numbering.h" 10 #include "src/ast/ast-numbering.h"
(...skipping 6557 matching lines...) Expand 10 before | Expand all | Expand 10 after
6568 int argument_count = 1; 6568 int argument_count = 1;
6569 if (!info->IsLoad()) { 6569 if (!info->IsLoad()) {
6570 argument_count = 2; 6570 argument_count = 2;
6571 Push(value); 6571 Push(value);
6572 } 6572 }
6573 6573
6574 if (info->accessor()->IsJSFunction() && 6574 if (info->accessor()->IsJSFunction() &&
6575 info->NeedsWrappingFor(Handle<JSFunction>::cast(info->accessor()))) { 6575 info->NeedsWrappingFor(Handle<JSFunction>::cast(info->accessor()))) {
6576 HValue* function = Add<HConstant>(info->accessor()); 6576 HValue* function = Add<HConstant>(info->accessor());
6577 PushArgumentsFromEnvironment(argument_count); 6577 PushArgumentsFromEnvironment(argument_count);
6578 return New<HCallFunction>(function, argument_count, 6578 return NewCallFunction(function, argument_count,
6579 ConvertReceiverMode::kNotNullOrUndefined); 6579 ConvertReceiverMode::kNotNullOrUndefined);
6580 } else if (FLAG_inline_accessors && can_inline_accessor) { 6580 } else if (FLAG_inline_accessors && can_inline_accessor) {
6581 bool success = info->IsLoad() 6581 bool success = info->IsLoad()
6582 ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id) 6582 ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id)
6583 : TryInlineSetter( 6583 : TryInlineSetter(
6584 info->accessor(), info->map(), ast_id, return_id, value); 6584 info->accessor(), info->map(), ast_id, return_id, value);
6585 if (success || HasStackOverflow()) return NULL; 6585 if (success || HasStackOverflow()) return NULL;
6586 } 6586 }
6587 6587
6588 PushArgumentsFromEnvironment(argument_count); 6588 PushArgumentsFromEnvironment(argument_count);
6589 if (!info->accessor()->IsJSFunction()) { 6589 if (!info->accessor()->IsJSFunction()) {
(...skipping 1392 matching lines...) Expand 10 before | Expand all | Expand 10 after
7982 7982
7983 7983
7984 void HOptimizedGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder, 7984 void HOptimizedGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder,
7985 Handle<Map> receiver_map) { 7985 Handle<Map> receiver_map) {
7986 if (!holder.is_null()) { 7986 if (!holder.is_null()) {
7987 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype())); 7987 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype()));
7988 BuildCheckPrototypeMaps(prototype, holder); 7988 BuildCheckPrototypeMaps(prototype, holder);
7989 } 7989 }
7990 } 7990 }
7991 7991
7992 7992 HInstruction* HOptimizedGraphBuilder::NewPlainFunctionCall(HValue* function,
7993 HInstruction* HOptimizedGraphBuilder::NewPlainFunctionCall(HValue* fun,
7994 int argument_count) { 7993 int argument_count) {
7995 return New<HCallJSFunction>(fun, argument_count); 7994 return New<HCallJSFunction>(function, argument_count);
7996 } 7995 }
7997 7996
7998
7999 HInstruction* HOptimizedGraphBuilder::NewArgumentAdaptorCall( 7997 HInstruction* HOptimizedGraphBuilder::NewArgumentAdaptorCall(
8000 HValue* fun, HValue* context, 7998 HValue* function, int argument_count, HValue* expected_param_count) {
8001 int argument_count, HValue* expected_param_count) { 7999 HValue* context = Add<HLoadNamedField>(
8000 function, nullptr, HObjectAccess::ForFunctionContextPointer());
8002 HValue* new_target = graph()->GetConstantUndefined(); 8001 HValue* new_target = graph()->GetConstantUndefined();
8003 HValue* arity = Add<HConstant>(argument_count - 1); 8002 HValue* arity = Add<HConstant>(argument_count - 1);
8004 8003
8005 HValue* op_vals[] = {context, fun, new_target, arity, expected_param_count}; 8004 HValue* op_vals[] = {context, function, new_target, arity,
8005 expected_param_count};
8006 8006
8007 Callable callable = CodeFactory::ArgumentAdaptor(isolate()); 8007 Callable callable = CodeFactory::ArgumentAdaptor(isolate());
8008 HConstant* stub = Add<HConstant>(callable.code()); 8008 HConstant* stub = Add<HConstant>(callable.code());
8009 8009
8010 return New<HCallWithDescriptor>(stub, argument_count, callable.descriptor(), 8010 return New<HCallWithDescriptor>(stub, argument_count, callable.descriptor(),
8011 Vector<HValue*>(op_vals, arraysize(op_vals))); 8011 Vector<HValue*>(op_vals, arraysize(op_vals)));
8012 } 8012 }
8013 8013
8014 HInstruction* HOptimizedGraphBuilder::NewCallFunction(
8015 HValue* function, int argument_count, ConvertReceiverMode convert_mode) {
8016 HValue* arity = Add<HConstant>(argument_count - 1);
8017
8018 HValue* op_vals[] = {context(), function, arity};
8019
8020 Callable callable = CodeFactory::Call(isolate(), convert_mode);
8021 HConstant* stub = Add<HConstant>(callable.code());
8022
8023 return New<HCallWithDescriptor>(stub, argument_count, callable.descriptor(),
8024 Vector<HValue*>(op_vals, arraysize(op_vals)));
8025 }
8026
8027 HInstruction* HOptimizedGraphBuilder::NewCallFunctionViaIC(
8028 HValue* function, int argument_count, ConvertReceiverMode convert_mode,
8029 FeedbackVectorSlot slot) {
8030 int arity = argument_count - 1;
8031 Handle<TypeFeedbackVector> vector(current_feedback_vector(), isolate());
8032 HValue* index_val = Add<HConstant>(vector->GetIndex(slot));
8033 HValue* vector_val = Add<HConstant>(vector);
8034
8035 HValue* op_vals[] = {context(), function, index_val, vector_val};
8036
8037 Callable callable = CodeFactory::CallICInOptimizedCode(
8038 isolate(), arity, ConvertReceiverMode::kNullOrUndefined);
8039 HConstant* stub = Add<HConstant>(callable.code());
8040
8041 return New<HCallWithDescriptor>(stub, argument_count, callable.descriptor(),
8042 Vector<HValue*>(op_vals, arraysize(op_vals)));
8043 }
8014 8044
8015 HInstruction* HOptimizedGraphBuilder::BuildCallConstantFunction( 8045 HInstruction* HOptimizedGraphBuilder::BuildCallConstantFunction(
8016 Handle<JSFunction> jsfun, int argument_count) { 8046 Handle<JSFunction> jsfun, int argument_count) {
8017 HValue* target = Add<HConstant>(jsfun); 8047 HValue* target = Add<HConstant>(jsfun);
8018 // For constant functions, we try to avoid calling the 8048 // For constant functions, we try to avoid calling the
8019 // argument adaptor and instead call the function directly 8049 // argument adaptor and instead call the function directly
8020 int formal_parameter_count = 8050 int formal_parameter_count =
8021 jsfun->shared()->internal_formal_parameter_count(); 8051 jsfun->shared()->internal_formal_parameter_count();
8022 bool dont_adapt_arguments = 8052 bool dont_adapt_arguments =
8023 (formal_parameter_count == 8053 (formal_parameter_count ==
8024 SharedFunctionInfo::kDontAdaptArgumentsSentinel); 8054 SharedFunctionInfo::kDontAdaptArgumentsSentinel);
8025 int arity = argument_count - 1; 8055 int arity = argument_count - 1;
8026 bool can_invoke_directly = 8056 bool can_invoke_directly =
8027 dont_adapt_arguments || formal_parameter_count == arity; 8057 dont_adapt_arguments || formal_parameter_count == arity;
8028 if (can_invoke_directly) { 8058 if (can_invoke_directly) {
8029 if (jsfun.is_identical_to(current_info()->closure())) { 8059 if (jsfun.is_identical_to(current_info()->closure())) {
8030 graph()->MarkRecursive(); 8060 graph()->MarkRecursive();
8031 } 8061 }
8032 return NewPlainFunctionCall(target, argument_count); 8062 return NewPlainFunctionCall(target, argument_count);
8033 } else { 8063 } else {
8034 HValue* param_count_value = Add<HConstant>(formal_parameter_count); 8064 HValue* param_count_value = Add<HConstant>(formal_parameter_count);
8035 HValue* context = Add<HLoadNamedField>( 8065 return NewArgumentAdaptorCall(target, argument_count, param_count_value);
8036 target, nullptr, HObjectAccess::ForFunctionContextPointer());
8037 return NewArgumentAdaptorCall(target, context,
8038 argument_count, param_count_value);
8039 } 8066 }
8040 UNREACHABLE(); 8067 UNREACHABLE();
8041 return NULL; 8068 return NULL;
8042 } 8069 }
8043 8070
8044 8071
8045 class FunctionSorter { 8072 class FunctionSorter {
8046 public: 8073 public:
8047 explicit FunctionSorter(int index = 0, int ticks = 0, int size = 0) 8074 explicit FunctionSorter(int index = 0, int ticks = 0, int size = 0)
8048 : index_(index), ticks_(ticks), size_(size) {} 8075 : index_(index), ticks_(ticks), size_(size) {}
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
8173 PrintF("Trying to inline the polymorphic call to %s from %s\n", 8200 PrintF("Trying to inline the polymorphic call to %s from %s\n",
8174 name->ToCString().get(), 8201 name->ToCString().get(),
8175 caller_name.get()); 8202 caller_name.get());
8176 } 8203 }
8177 if (try_inline && TryInlineCall(expr)) { 8204 if (try_inline && TryInlineCall(expr)) {
8178 // Trying to inline will signal that we should bailout from the 8205 // Trying to inline will signal that we should bailout from the
8179 // entire compilation by setting stack overflow on the visitor. 8206 // entire compilation by setting stack overflow on the visitor.
8180 if (HasStackOverflow()) return; 8207 if (HasStackOverflow()) return;
8181 } else { 8208 } else {
8182 // Since HWrapReceiver currently cannot actually wrap numbers and strings, 8209 // Since HWrapReceiver currently cannot actually wrap numbers and strings,
8183 // use the regular CallFunctionStub for method calls to wrap the receiver. 8210 // use the regular call builtin for method calls to wrap the receiver.
8184 // TODO(verwaest): Support creation of value wrappers directly in 8211 // TODO(verwaest): Support creation of value wrappers directly in
8185 // HWrapReceiver. 8212 // HWrapReceiver.
8186 HInstruction* call = 8213 HInstruction* call =
8187 needs_wrapping ? NewUncasted<HCallFunction>( 8214 needs_wrapping
8188 function, argument_count, 8215 ? NewCallFunction(function, argument_count,
8189 ConvertReceiverMode::kNotNullOrUndefined) 8216 ConvertReceiverMode::kNotNullOrUndefined)
8190 : BuildCallConstantFunction(target, argument_count); 8217 : BuildCallConstantFunction(target, argument_count);
8191 PushArgumentsFromEnvironment(argument_count); 8218 PushArgumentsFromEnvironment(argument_count);
8192 AddInstruction(call); 8219 AddInstruction(call);
8193 Drop(1); // Drop the function. 8220 Drop(1); // Drop the function.
8194 if (!ast_context()->IsEffect()) Push(call); 8221 if (!ast_context()->IsEffect()) Push(call);
8195 } 8222 }
8196 8223
8197 if (current_block() != NULL) Goto(join); 8224 if (current_block() != NULL) Goto(join);
8198 set_current_block(if_false); 8225 set_current_block(if_false);
8199 } 8226 }
8200 8227
8201 // Finish up. Unconditionally deoptimize if we've handled all the maps we 8228 // Finish up. Unconditionally deoptimize if we've handled all the maps we
8202 // know about and do not want to handle ones we've never seen. Otherwise 8229 // know about and do not want to handle ones we've never seen. Otherwise
8203 // use a generic IC. 8230 // use a generic IC.
8204 if (ordered_functions == maps->length() && FLAG_deoptimize_uncommon_cases) { 8231 if (ordered_functions == maps->length() && FLAG_deoptimize_uncommon_cases) {
8205 FinishExitWithHardDeoptimization(Deoptimizer::kUnknownMapInPolymorphicCall); 8232 FinishExitWithHardDeoptimization(Deoptimizer::kUnknownMapInPolymorphicCall);
8206 } else { 8233 } else {
8207 Property* prop = expr->expression()->AsProperty(); 8234 Property* prop = expr->expression()->AsProperty();
8208 HInstruction* function = 8235 HInstruction* function =
8209 BuildNamedGeneric(LOAD, prop, prop->PropertyFeedbackSlot(), receiver, 8236 BuildNamedGeneric(LOAD, prop, prop->PropertyFeedbackSlot(), receiver,
8210 name, NULL, prop->IsUninitialized()); 8237 name, NULL, prop->IsUninitialized());
8211 AddInstruction(function); 8238 AddInstruction(function);
8212 Push(function); 8239 Push(function);
8213 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); 8240 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE);
8214 8241
8215 environment()->SetExpressionStackAt(1, function); 8242 environment()->SetExpressionStackAt(1, function);
8216 environment()->SetExpressionStackAt(0, receiver); 8243 environment()->SetExpressionStackAt(0, receiver);
8217 CHECK_ALIVE(VisitExpressions(expr->arguments())); 8244 CHECK_ALIVE(VisitExpressions(expr->arguments()));
8218 8245
8219 HInstruction* call = New<HCallFunction>( 8246 HInstruction* call = NewCallFunction(
8220 function, argument_count, ConvertReceiverMode::kNotNullOrUndefined); 8247 function, argument_count, ConvertReceiverMode::kNotNullOrUndefined);
8221 8248
8222 PushArgumentsFromEnvironment(argument_count); 8249 PushArgumentsFromEnvironment(argument_count);
8223 8250
8224 Drop(1); // Function. 8251 Drop(1); // Function.
8225 8252
8226 if (join != NULL) { 8253 if (join != NULL) {
8227 AddInstruction(call); 8254 AddInstruction(call);
8228 if (!ast_context()->IsEffect()) Push(call); 8255 if (!ast_context()->IsEffect()) Push(call);
8229 Goto(join); 8256 Goto(join);
(...skipping 1513 matching lines...) Expand 10 before | Expand all | Expand 10 after
9743 known_function->ShortPrint(); 9770 known_function->ShortPrint();
9744 PrintF("\n"); 9771 PrintF("\n");
9745 } 9772 }
9746 return; 9773 return;
9747 } 9774 }
9748 if (TryInlineApiMethodCall(expr, receiver, maps)) return; 9775 if (TryInlineApiMethodCall(expr, receiver, maps)) return;
9749 9776
9750 // Wrap the receiver if necessary. 9777 // Wrap the receiver if necessary.
9751 if (NeedsWrapping(maps->first(), known_function)) { 9778 if (NeedsWrapping(maps->first(), known_function)) {
9752 // Since HWrapReceiver currently cannot actually wrap numbers and 9779 // Since HWrapReceiver currently cannot actually wrap numbers and
9753 // strings, use the regular CallFunctionStub for method calls to wrap 9780 // strings, use the regular call builtin for method calls to wrap
9754 // the receiver. 9781 // the receiver.
9755 // TODO(verwaest): Support creation of value wrappers directly in 9782 // TODO(verwaest): Support creation of value wrappers directly in
9756 // HWrapReceiver. 9783 // HWrapReceiver.
9757 call = New<HCallFunction>(function, argument_count, 9784 call = NewCallFunction(function, argument_count,
9758 ConvertReceiverMode::kNotNullOrUndefined); 9785 ConvertReceiverMode::kNotNullOrUndefined);
9759 } else if (TryInlineCall(expr)) { 9786 } else if (TryInlineCall(expr)) {
9760 return; 9787 return;
9761 } else { 9788 } else {
9762 call = BuildCallConstantFunction(known_function, argument_count); 9789 call = BuildCallConstantFunction(known_function, argument_count);
9763 } 9790 }
9764 9791
9765 } else { 9792 } else {
9766 ArgumentsAllowedFlag arguments_flag = ARGUMENTS_NOT_ALLOWED; 9793 ArgumentsAllowedFlag arguments_flag = ARGUMENTS_NOT_ALLOWED;
9767 if (CanBeFunctionApplyArguments(expr) && expr->is_uninitialized()) { 9794 if (CanBeFunctionApplyArguments(expr) && expr->is_uninitialized()) {
9768 // We have to use EAGER deoptimization here because Deoptimizer::SOFT 9795 // We have to use EAGER deoptimization here because Deoptimizer::SOFT
9769 // gets ignored by the always-opt flag, which leads to incorrect code. 9796 // gets ignored by the always-opt flag, which leads to incorrect code.
9770 Add<HDeoptimize>( 9797 Add<HDeoptimize>(
9771 Deoptimizer::kInsufficientTypeFeedbackForCallWithArguments, 9798 Deoptimizer::kInsufficientTypeFeedbackForCallWithArguments,
9772 Deoptimizer::EAGER); 9799 Deoptimizer::EAGER);
9773 arguments_flag = ARGUMENTS_FAKED; 9800 arguments_flag = ARGUMENTS_FAKED;
9774 } 9801 }
9775 9802
9776 // Push the function under the receiver. 9803 // Push the function under the receiver.
9777 environment()->SetExpressionStackAt(0, function); 9804 environment()->SetExpressionStackAt(0, function);
9778 Push(receiver); 9805 Push(receiver);
9779 9806
9780 CHECK_ALIVE(VisitExpressions(expr->arguments(), arguments_flag)); 9807 CHECK_ALIVE(VisitExpressions(expr->arguments(), arguments_flag));
9781 call = New<HCallFunction>(function, argument_count, 9808 call = NewCallFunction(function, argument_count,
9782 ConvertReceiverMode::kNotNullOrUndefined); 9809 ConvertReceiverMode::kNotNullOrUndefined);
9783 } 9810 }
9784 PushArgumentsFromEnvironment(argument_count); 9811 PushArgumentsFromEnvironment(argument_count);
9785 9812
9786 } else { 9813 } else {
9787 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 9814 VariableProxy* proxy = expr->expression()->AsVariableProxy();
9788 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { 9815 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) {
9789 return Bailout(kPossibleDirectCallToEval); 9816 return Bailout(kPossibleDirectCallToEval);
9790 } 9817 }
9791 9818
9792 // The function is on the stack in the unoptimized code during 9819 // The function is on the stack in the unoptimized code during
(...skipping 29 matching lines...) Expand all
9822 return; 9849 return;
9823 } 9850 }
9824 if (TryInlineApiFunctionCall(expr, receiver)) return; 9851 if (TryInlineApiFunctionCall(expr, receiver)) return;
9825 if (TryHandleArrayCall(expr, function)) return; 9852 if (TryHandleArrayCall(expr, function)) return;
9826 if (TryInlineCall(expr)) return; 9853 if (TryInlineCall(expr)) return;
9827 9854
9828 PushArgumentsFromEnvironment(argument_count); 9855 PushArgumentsFromEnvironment(argument_count);
9829 call = BuildCallConstantFunction(expr->target(), argument_count); 9856 call = BuildCallConstantFunction(expr->target(), argument_count);
9830 } else { 9857 } else {
9831 PushArgumentsFromEnvironment(argument_count); 9858 PushArgumentsFromEnvironment(argument_count);
9832 HCallFunction* call_function = New<HCallFunction>(
9833 function, argument_count, ConvertReceiverMode::kNullOrUndefined);
9834 call = call_function;
9835 if (expr->is_uninitialized() && 9859 if (expr->is_uninitialized() &&
9836 expr->IsUsingCallFeedbackICSlot(isolate())) { 9860 expr->IsUsingCallFeedbackICSlot(isolate())) {
9837 // We've never seen this call before, so let's have Crankshaft learn 9861 // We've never seen this call before, so let's have Crankshaft learn
9838 // through the type vector. 9862 // through the type vector.
9839 Handle<TypeFeedbackVector> vector = 9863 call = NewCallFunctionViaIC(function, argument_count,
9840 handle(current_feedback_vector(), isolate()); 9864 ConvertReceiverMode::kNullOrUndefined,
9841 FeedbackVectorSlot slot = expr->CallFeedbackICSlot(); 9865 expr->CallFeedbackICSlot());
9842 call_function->SetVectorAndSlot(vector, slot); 9866 } else {
9867 call = NewCallFunction(function, argument_count,
9868 ConvertReceiverMode::kNullOrUndefined);
9843 } 9869 }
9844 } 9870 }
9845 } 9871 }
9846 9872
9847 Drop(1); // Drop the function. 9873 Drop(1); // Drop the function.
9848 return ast_context()->ReturnInstruction(call, expr->id()); 9874 return ast_context()->ReturnInstruction(call, expr->id());
9849 } 9875 }
9850 9876
9851 9877
9852 void HOptimizedGraphBuilder::BuildInlinedCallArray( 9878 void HOptimizedGraphBuilder::BuildInlinedCallArray(
(...skipping 3618 matching lines...) Expand 10 before | Expand all | Expand 10 after
13471 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 13497 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
13472 } 13498 }
13473 13499
13474 #ifdef DEBUG 13500 #ifdef DEBUG
13475 graph_->Verify(false); // No full verify. 13501 graph_->Verify(false); // No full verify.
13476 #endif 13502 #endif
13477 } 13503 }
13478 13504
13479 } // namespace internal 13505 } // namespace internal
13480 } // namespace v8 13506 } // namespace v8
OLDNEW
« no previous file with comments | « src/crankshaft/hydrogen.h ('k') | src/crankshaft/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698