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

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

Issue 1436493002: [builtins] Introduce specialized Call/CallFunction builtins. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 1 month 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/arm64/lithium-codegen-arm64.cc ('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-numbering.h" 10 #include "src/ast-numbering.h"
(...skipping 6571 matching lines...) Expand 10 before | Expand all | Expand 10 after
6582 Push(checked_object); 6582 Push(checked_object);
6583 int argument_count = 1; 6583 int argument_count = 1;
6584 if (!info->IsLoad()) { 6584 if (!info->IsLoad()) {
6585 argument_count = 2; 6585 argument_count = 2;
6586 Push(value); 6586 Push(value);
6587 } 6587 }
6588 6588
6589 if (info->NeedsWrappingFor(info->accessor())) { 6589 if (info->NeedsWrappingFor(info->accessor())) {
6590 HValue* function = Add<HConstant>(info->accessor()); 6590 HValue* function = Add<HConstant>(info->accessor());
6591 PushArgumentsFromEnvironment(argument_count); 6591 PushArgumentsFromEnvironment(argument_count);
6592 return New<HCallFunction>(function, argument_count); 6592 return New<HCallFunction>(function, argument_count,
6593 ConvertReceiverMode::kNotNullOrUndefined);
6593 } else if (FLAG_inline_accessors && can_inline_accessor) { 6594 } else if (FLAG_inline_accessors && can_inline_accessor) {
6594 bool success = info->IsLoad() 6595 bool success = info->IsLoad()
6595 ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id) 6596 ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id)
6596 : TryInlineSetter( 6597 : TryInlineSetter(
6597 info->accessor(), info->map(), ast_id, return_id, value); 6598 info->accessor(), info->map(), ast_id, return_id, value);
6598 if (success || HasStackOverflow()) return NULL; 6599 if (success || HasStackOverflow()) return NULL;
6599 } 6600 }
6600 6601
6601 PushArgumentsFromEnvironment(argument_count); 6602 PushArgumentsFromEnvironment(argument_count);
6602 return BuildCallConstantFunction(info->accessor(), argument_count); 6603 return BuildCallConstantFunction(info->accessor(), argument_count);
(...skipping 1560 matching lines...) Expand 10 before | Expand all | Expand 10 after
8163 if (try_inline && TryInlineCall(expr)) { 8164 if (try_inline && TryInlineCall(expr)) {
8164 // Trying to inline will signal that we should bailout from the 8165 // Trying to inline will signal that we should bailout from the
8165 // entire compilation by setting stack overflow on the visitor. 8166 // entire compilation by setting stack overflow on the visitor.
8166 if (HasStackOverflow()) return; 8167 if (HasStackOverflow()) return;
8167 } else { 8168 } else {
8168 // Since HWrapReceiver currently cannot actually wrap numbers and strings, 8169 // Since HWrapReceiver currently cannot actually wrap numbers and strings,
8169 // use the regular CallFunctionStub for method calls to wrap the receiver. 8170 // use the regular CallFunctionStub for method calls to wrap the receiver.
8170 // TODO(verwaest): Support creation of value wrappers directly in 8171 // TODO(verwaest): Support creation of value wrappers directly in
8171 // HWrapReceiver. 8172 // HWrapReceiver.
8172 HInstruction* call = 8173 HInstruction* call =
8173 needs_wrapping ? NewUncasted<HCallFunction>(function, argument_count) 8174 needs_wrapping ? NewUncasted<HCallFunction>(
8175 function, argument_count,
8176 ConvertReceiverMode::kNotNullOrUndefined)
8174 : BuildCallConstantFunction(target, argument_count); 8177 : BuildCallConstantFunction(target, argument_count);
8175 PushArgumentsFromEnvironment(argument_count); 8178 PushArgumentsFromEnvironment(argument_count);
8176 AddInstruction(call); 8179 AddInstruction(call);
8177 Drop(1); // Drop the function. 8180 Drop(1); // Drop the function.
8178 if (!ast_context()->IsEffect()) Push(call); 8181 if (!ast_context()->IsEffect()) Push(call);
8179 } 8182 }
8180 8183
8181 if (current_block() != NULL) Goto(join); 8184 if (current_block() != NULL) Goto(join);
8182 set_current_block(if_false); 8185 set_current_block(if_false);
8183 } 8186 }
8184 8187
8185 // Finish up. Unconditionally deoptimize if we've handled all the maps we 8188 // Finish up. Unconditionally deoptimize if we've handled all the maps we
8186 // know about and do not want to handle ones we've never seen. Otherwise 8189 // know about and do not want to handle ones we've never seen. Otherwise
8187 // use a generic IC. 8190 // use a generic IC.
8188 if (ordered_functions == maps->length() && FLAG_deoptimize_uncommon_cases) { 8191 if (ordered_functions == maps->length() && FLAG_deoptimize_uncommon_cases) {
8189 FinishExitWithHardDeoptimization(Deoptimizer::kUnknownMapInPolymorphicCall); 8192 FinishExitWithHardDeoptimization(Deoptimizer::kUnknownMapInPolymorphicCall);
8190 } else { 8193 } else {
8191 Property* prop = expr->expression()->AsProperty(); 8194 Property* prop = expr->expression()->AsProperty();
8192 HInstruction* function = 8195 HInstruction* function =
8193 BuildNamedGeneric(LOAD, prop, prop->PropertyFeedbackSlot(), receiver, 8196 BuildNamedGeneric(LOAD, prop, prop->PropertyFeedbackSlot(), receiver,
8194 name, NULL, prop->IsUninitialized()); 8197 name, NULL, prop->IsUninitialized());
8195 AddInstruction(function); 8198 AddInstruction(function);
8196 Push(function); 8199 Push(function);
8197 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); 8200 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE);
8198 8201
8199 environment()->SetExpressionStackAt(1, function); 8202 environment()->SetExpressionStackAt(1, function);
8200 environment()->SetExpressionStackAt(0, receiver); 8203 environment()->SetExpressionStackAt(0, receiver);
8201 CHECK_ALIVE(VisitExpressions(expr->arguments())); 8204 CHECK_ALIVE(VisitExpressions(expr->arguments()));
8202 8205
8203 HInstruction* call = New<HCallFunction>(function, argument_count); 8206 HInstruction* call = New<HCallFunction>(
8207 function, argument_count, ConvertReceiverMode::kNotNullOrUndefined);
8204 8208
8205 PushArgumentsFromEnvironment(argument_count); 8209 PushArgumentsFromEnvironment(argument_count);
8206 8210
8207 Drop(1); // Function. 8211 Drop(1); // Function.
8208 8212
8209 if (join != NULL) { 8213 if (join != NULL) {
8210 AddInstruction(call); 8214 AddInstruction(call);
8211 if (!ast_context()->IsEffect()) Push(call); 8215 if (!ast_context()->IsEffect()) Push(call);
8212 Goto(join); 8216 Goto(join);
8213 } else { 8217 } else {
(...skipping 1488 matching lines...) Expand 10 before | Expand all | Expand 10 after
9702 } 9706 }
9703 if (TryInlineApiMethodCall(expr, receiver, maps)) return; 9707 if (TryInlineApiMethodCall(expr, receiver, maps)) return;
9704 9708
9705 // Wrap the receiver if necessary. 9709 // Wrap the receiver if necessary.
9706 if (NeedsWrapping(maps->first(), known_function)) { 9710 if (NeedsWrapping(maps->first(), known_function)) {
9707 // Since HWrapReceiver currently cannot actually wrap numbers and 9711 // Since HWrapReceiver currently cannot actually wrap numbers and
9708 // strings, use the regular CallFunctionStub for method calls to wrap 9712 // strings, use the regular CallFunctionStub for method calls to wrap
9709 // the receiver. 9713 // the receiver.
9710 // TODO(verwaest): Support creation of value wrappers directly in 9714 // TODO(verwaest): Support creation of value wrappers directly in
9711 // HWrapReceiver. 9715 // HWrapReceiver.
9712 call = New<HCallFunction>(function, argument_count); 9716 call = New<HCallFunction>(function, argument_count,
9717 ConvertReceiverMode::kNotNullOrUndefined);
9713 } else if (TryInlineCall(expr)) { 9718 } else if (TryInlineCall(expr)) {
9714 return; 9719 return;
9715 } else { 9720 } else {
9716 call = BuildCallConstantFunction(known_function, argument_count); 9721 call = BuildCallConstantFunction(known_function, argument_count);
9717 } 9722 }
9718 9723
9719 } else { 9724 } else {
9720 ArgumentsAllowedFlag arguments_flag = ARGUMENTS_NOT_ALLOWED; 9725 ArgumentsAllowedFlag arguments_flag = ARGUMENTS_NOT_ALLOWED;
9721 if (CanBeFunctionApplyArguments(expr) && expr->is_uninitialized()) { 9726 if (CanBeFunctionApplyArguments(expr) && expr->is_uninitialized()) {
9722 // We have to use EAGER deoptimization here because Deoptimizer::SOFT 9727 // We have to use EAGER deoptimization here because Deoptimizer::SOFT
9723 // gets ignored by the always-opt flag, which leads to incorrect code. 9728 // gets ignored by the always-opt flag, which leads to incorrect code.
9724 Add<HDeoptimize>( 9729 Add<HDeoptimize>(
9725 Deoptimizer::kInsufficientTypeFeedbackForCallWithArguments, 9730 Deoptimizer::kInsufficientTypeFeedbackForCallWithArguments,
9726 Deoptimizer::EAGER); 9731 Deoptimizer::EAGER);
9727 arguments_flag = ARGUMENTS_FAKED; 9732 arguments_flag = ARGUMENTS_FAKED;
9728 } 9733 }
9729 9734
9730 // Push the function under the receiver. 9735 // Push the function under the receiver.
9731 environment()->SetExpressionStackAt(0, function); 9736 environment()->SetExpressionStackAt(0, function);
9732 Push(receiver); 9737 Push(receiver);
9733 9738
9734 CHECK_ALIVE(VisitExpressions(expr->arguments(), arguments_flag)); 9739 CHECK_ALIVE(VisitExpressions(expr->arguments(), arguments_flag));
9735 call = New<HCallFunction>(function, argument_count); 9740 call = New<HCallFunction>(function, argument_count,
9741 ConvertReceiverMode::kNotNullOrUndefined);
9736 } 9742 }
9737 PushArgumentsFromEnvironment(argument_count); 9743 PushArgumentsFromEnvironment(argument_count);
9738 9744
9739 } else { 9745 } else {
9740 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 9746 VariableProxy* proxy = expr->expression()->AsVariableProxy();
9741 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { 9747 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) {
9742 return Bailout(kPossibleDirectCallToEval); 9748 return Bailout(kPossibleDirectCallToEval);
9743 } 9749 }
9744 9750
9745 // The function is on the stack in the unoptimized code during 9751 // The function is on the stack in the unoptimized code during
(...skipping 29 matching lines...) Expand all
9775 return; 9781 return;
9776 } 9782 }
9777 if (TryInlineApiFunctionCall(expr, receiver)) return; 9783 if (TryInlineApiFunctionCall(expr, receiver)) return;
9778 if (TryHandleArrayCall(expr, function)) return; 9784 if (TryHandleArrayCall(expr, function)) return;
9779 if (TryInlineCall(expr)) return; 9785 if (TryInlineCall(expr)) return;
9780 9786
9781 PushArgumentsFromEnvironment(argument_count); 9787 PushArgumentsFromEnvironment(argument_count);
9782 call = BuildCallConstantFunction(expr->target(), argument_count); 9788 call = BuildCallConstantFunction(expr->target(), argument_count);
9783 } else { 9789 } else {
9784 PushArgumentsFromEnvironment(argument_count); 9790 PushArgumentsFromEnvironment(argument_count);
9785 HCallFunction* call_function = 9791 HCallFunction* call_function = New<HCallFunction>(
9786 New<HCallFunction>(function, argument_count); 9792 function, argument_count, ConvertReceiverMode::kNullOrUndefined);
9787 call = call_function; 9793 call = call_function;
9788 if (expr->is_uninitialized() && 9794 if (expr->is_uninitialized() &&
9789 expr->IsUsingCallFeedbackICSlot(isolate())) { 9795 expr->IsUsingCallFeedbackICSlot(isolate())) {
9790 // We've never seen this call before, so let's have Crankshaft learn 9796 // We've never seen this call before, so let's have Crankshaft learn
9791 // through the type vector. 9797 // through the type vector.
9792 Handle<TypeFeedbackVector> vector = 9798 Handle<TypeFeedbackVector> vector =
9793 handle(current_feedback_vector(), isolate()); 9799 handle(current_feedback_vector(), isolate());
9794 FeedbackVectorSlot slot = expr->CallFeedbackICSlot(); 9800 FeedbackVectorSlot slot = expr->CallFeedbackICSlot();
9795 call_function->SetVectorAndSlot(vector, slot); 9801 call_function->SetVectorAndSlot(vector, slot);
9796 } 9802 }
(...skipping 3835 matching lines...) Expand 10 before | Expand all | Expand 10 after
13632 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 13638 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
13633 } 13639 }
13634 13640
13635 #ifdef DEBUG 13641 #ifdef DEBUG
13636 graph_->Verify(false); // No full verify. 13642 graph_->Verify(false); // No full verify.
13637 #endif 13643 #endif
13638 } 13644 }
13639 13645
13640 } // namespace internal 13646 } // namespace internal
13641 } // namespace v8 13647 } // namespace v8
OLDNEW
« no previous file with comments | « src/crankshaft/arm64/lithium-codegen-arm64.cc ('k') | src/crankshaft/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698