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

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

Issue 1780043004: [crankshaft] Fixing ES6 tail call elimination. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Ignition crash is not related to TCE, issue number updated 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
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 5491 matching lines...) Expand 10 before | Expand all | Expand 10 after
5502 // Use the fast case closure allocation code that allocates in new 5502 // Use the fast case closure allocation code that allocates in new
5503 // space for nested functions that don't need literals cloning. 5503 // space for nested functions that don't need literals cloning.
5504 HConstant* shared_info_value = Add<HConstant>(shared_info); 5504 HConstant* shared_info_value = Add<HConstant>(shared_info);
5505 HInstruction* instr; 5505 HInstruction* instr;
5506 if (!expr->pretenure() && shared_info->num_literals() == 0) { 5506 if (!expr->pretenure() && shared_info->num_literals() == 0) {
5507 FastNewClosureStub stub(isolate(), shared_info->language_mode(), 5507 FastNewClosureStub stub(isolate(), shared_info->language_mode(),
5508 shared_info->kind()); 5508 shared_info->kind());
5509 FastNewClosureDescriptor descriptor(isolate()); 5509 FastNewClosureDescriptor descriptor(isolate());
5510 HValue* values[] = {context(), shared_info_value}; 5510 HValue* values[] = {context(), shared_info_value};
5511 HConstant* stub_value = Add<HConstant>(stub.GetCode()); 5511 HConstant* stub_value = Add<HConstant>(stub.GetCode());
5512 instr = New<HCallWithDescriptor>(stub_value, 0, descriptor, 5512 instr = New<HCallWithDescriptor>(
5513 Vector<HValue*>(values, arraysize(values)), 5513 stub_value, 0, descriptor, Vector<HValue*>(values, arraysize(values)));
5514 NORMAL_CALL);
5515 } else { 5514 } else {
5516 Add<HPushArguments>(shared_info_value); 5515 Add<HPushArguments>(shared_info_value);
5517 Runtime::FunctionId function_id = 5516 Runtime::FunctionId function_id =
5518 expr->pretenure() ? Runtime::kNewClosure_Tenured : Runtime::kNewClosure; 5517 expr->pretenure() ? Runtime::kNewClosure_Tenured : Runtime::kNewClosure;
5519 instr = New<HCallRuntime>(Runtime::FunctionForId(function_id), 1); 5518 instr = New<HCallRuntime>(Runtime::FunctionForId(function_id), 1);
5520 } 5519 }
5521 return ast_context()->ReturnInstruction(instr, expr->id()); 5520 return ast_context()->ReturnInstruction(instr, expr->id());
5522 } 5521 }
5523 5522
5524 5523
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
5785 5784
5786 void HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { 5785 void HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
5787 DCHECK(!HasStackOverflow()); 5786 DCHECK(!HasStackOverflow());
5788 DCHECK(current_block() != NULL); 5787 DCHECK(current_block() != NULL);
5789 DCHECK(current_block()->HasPredecessor()); 5788 DCHECK(current_block()->HasPredecessor());
5790 Callable callable = CodeFactory::FastCloneRegExp(isolate()); 5789 Callable callable = CodeFactory::FastCloneRegExp(isolate());
5791 HValue* values[] = { 5790 HValue* values[] = {
5792 context(), AddThisFunction(), Add<HConstant>(expr->literal_index()), 5791 context(), AddThisFunction(), Add<HConstant>(expr->literal_index()),
5793 Add<HConstant>(expr->pattern()), Add<HConstant>(expr->flags())}; 5792 Add<HConstant>(expr->pattern()), Add<HConstant>(expr->flags())};
5794 HConstant* stub_value = Add<HConstant>(callable.code()); 5793 HConstant* stub_value = Add<HConstant>(callable.code());
5795 HInstruction* instr = New<HCallWithDescriptor>( 5794 HInstruction* instr =
5796 stub_value, 0, callable.descriptor(), 5795 New<HCallWithDescriptor>(stub_value, 0, callable.descriptor(),
5797 Vector<HValue*>(values, arraysize(values)), NORMAL_CALL); 5796 Vector<HValue*>(values, arraysize(values)));
5798 return ast_context()->ReturnInstruction(instr, expr->id()); 5797 return ast_context()->ReturnInstruction(instr, expr->id());
5799 } 5798 }
5800 5799
5801 5800
5802 static bool CanInlinePropertyAccess(Handle<Map> map) { 5801 static bool CanInlinePropertyAccess(Handle<Map> map) {
5803 if (map->instance_type() == HEAP_NUMBER_TYPE) return true; 5802 if (map->instance_type() == HEAP_NUMBER_TYPE) return true;
5804 if (map->instance_type() < FIRST_NONSTRING_TYPE) return true; 5803 if (map->instance_type() < FIRST_NONSTRING_TYPE) return true;
5805 return map->IsJSObjectMap() && !map->is_dictionary_map() && 5804 return map->IsJSObjectMap() && !map->is_dictionary_map() &&
5806 !map->has_named_interceptor() && 5805 !map->has_named_interceptor() &&
5807 // TODO(verwaest): Whitelist contexts to which we have access. 5806 // TODO(verwaest): Whitelist contexts to which we have access.
(...skipping 770 matching lines...) Expand 10 before | Expand all | Expand 10 after
6578 int argument_count = 1; 6577 int argument_count = 1;
6579 if (!info->IsLoad()) { 6578 if (!info->IsLoad()) {
6580 argument_count = 2; 6579 argument_count = 2;
6581 Push(value); 6580 Push(value);
6582 } 6581 }
6583 6582
6584 if (info->accessor()->IsJSFunction() && 6583 if (info->accessor()->IsJSFunction() &&
6585 info->NeedsWrappingFor(Handle<JSFunction>::cast(info->accessor()))) { 6584 info->NeedsWrappingFor(Handle<JSFunction>::cast(info->accessor()))) {
6586 HValue* function = Add<HConstant>(info->accessor()); 6585 HValue* function = Add<HConstant>(info->accessor());
6587 PushArgumentsFromEnvironment(argument_count); 6586 PushArgumentsFromEnvironment(argument_count);
6588 return NewCallFunction(function, argument_count, 6587 return NewCallFunction(function, argument_count, TailCallMode::kDisallow,
6589 ConvertReceiverMode::kNotNullOrUndefined, 6588 ConvertReceiverMode::kNotNullOrUndefined,
6590 TailCallMode::kDisallow); 6589 TailCallMode::kDisallow);
6591 } else if (FLAG_inline_accessors && can_inline_accessor) { 6590 } else if (FLAG_inline_accessors && can_inline_accessor) {
6592 bool success = info->IsLoad() 6591 bool success = info->IsLoad()
6593 ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id) 6592 ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id)
6594 : TryInlineSetter( 6593 : TryInlineSetter(
6595 info->accessor(), info->map(), ast_id, return_id, value); 6594 info->accessor(), info->map(), ast_id, return_id, value);
6596 if (success || HasStackOverflow()) return NULL; 6595 if (success || HasStackOverflow()) return NULL;
6597 } 6596 }
6598 6597
6599 PushArgumentsFromEnvironment(argument_count); 6598 PushArgumentsFromEnvironment(argument_count);
6600 if (!info->accessor()->IsJSFunction()) { 6599 if (!info->accessor()->IsJSFunction()) {
6601 Bailout(kInliningBailedOut); 6600 Bailout(kInliningBailedOut);
6602 return nullptr; 6601 return nullptr;
6603 } 6602 }
6604 return NewCallConstantFunction(Handle<JSFunction>::cast(info->accessor()), 6603 return NewCallConstantFunction(Handle<JSFunction>::cast(info->accessor()),
6605 argument_count, TailCallMode::kDisallow); 6604 argument_count, TailCallMode::kDisallow,
6605 TailCallMode::kDisallow);
6606 } 6606 }
6607 6607
6608 DCHECK(info->IsDataConstant()); 6608 DCHECK(info->IsDataConstant());
6609 if (info->IsLoad()) { 6609 if (info->IsLoad()) {
6610 return New<HConstant>(info->constant()); 6610 return New<HConstant>(info->constant());
6611 } else { 6611 } else {
6612 return New<HCheckValue>(value, Handle<JSFunction>::cast(info->constant())); 6612 return New<HCheckValue>(value, Handle<JSFunction>::cast(info->constant()));
6613 } 6613 }
6614 } 6614 }
6615 6615
(...skipping 1378 matching lines...) Expand 10 before | Expand all | Expand 10 after
7994 7994
7995 void HOptimizedGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder, 7995 void HOptimizedGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder,
7996 Handle<Map> receiver_map) { 7996 Handle<Map> receiver_map) {
7997 if (!holder.is_null()) { 7997 if (!holder.is_null()) {
7998 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype())); 7998 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype()));
7999 BuildCheckPrototypeMaps(prototype, holder); 7999 BuildCheckPrototypeMaps(prototype, holder);
8000 } 8000 }
8001 } 8001 }
8002 8002
8003 HInstruction* HOptimizedGraphBuilder::NewCallFunction( 8003 HInstruction* HOptimizedGraphBuilder::NewCallFunction(
8004 HValue* function, int argument_count, ConvertReceiverMode convert_mode, 8004 HValue* function, int argument_count, TailCallMode syntactic_tail_call_mode,
8005 TailCallMode tail_call_mode) { 8005 ConvertReceiverMode convert_mode, TailCallMode tail_call_mode) {
8006 HValue* arity = Add<HConstant>(argument_count - 1); 8006 HValue* arity = Add<HConstant>(argument_count - 1);
8007 8007
8008 HValue* op_vals[] = {context(), function, arity}; 8008 HValue* op_vals[] = {context(), function, arity};
8009 8009
8010 Callable callable = 8010 Callable callable =
8011 CodeFactory::Call(isolate(), convert_mode, tail_call_mode); 8011 CodeFactory::Call(isolate(), convert_mode, tail_call_mode);
8012 HConstant* stub = Add<HConstant>(callable.code()); 8012 HConstant* stub = Add<HConstant>(callable.code());
8013 8013
8014 return New<HCallWithDescriptor>(stub, argument_count, callable.descriptor(), 8014 return New<HCallWithDescriptor>(stub, argument_count, callable.descriptor(),
8015 Vector<HValue*>(op_vals, arraysize(op_vals))); 8015 Vector<HValue*>(op_vals, arraysize(op_vals)),
8016 syntactic_tail_call_mode);
8016 } 8017 }
8017 8018
8018 HInstruction* HOptimizedGraphBuilder::NewCallFunctionViaIC( 8019 HInstruction* HOptimizedGraphBuilder::NewCallFunctionViaIC(
8019 HValue* function, int argument_count, ConvertReceiverMode convert_mode, 8020 HValue* function, int argument_count, TailCallMode syntactic_tail_call_mode,
8020 TailCallMode tail_call_mode, FeedbackVectorSlot slot) { 8021 ConvertReceiverMode convert_mode, TailCallMode tail_call_mode,
8022 FeedbackVectorSlot slot) {
8021 int arity = argument_count - 1; 8023 int arity = argument_count - 1;
8022 Handle<TypeFeedbackVector> vector(current_feedback_vector(), isolate()); 8024 Handle<TypeFeedbackVector> vector(current_feedback_vector(), isolate());
8023 HValue* index_val = Add<HConstant>(vector->GetIndex(slot)); 8025 HValue* index_val = Add<HConstant>(vector->GetIndex(slot));
8024 HValue* vector_val = Add<HConstant>(vector); 8026 HValue* vector_val = Add<HConstant>(vector);
8025 8027
8026 HValue* op_vals[] = {context(), function, index_val, vector_val}; 8028 HValue* op_vals[] = {context(), function, index_val, vector_val};
8027 8029
8028 Callable callable = CodeFactory::CallICInOptimizedCode( 8030 Callable callable = CodeFactory::CallICInOptimizedCode(
8029 isolate(), arity, ConvertReceiverMode::kNullOrUndefined, tail_call_mode); 8031 isolate(), arity, ConvertReceiverMode::kNullOrUndefined, tail_call_mode);
8030 HConstant* stub = Add<HConstant>(callable.code()); 8032 HConstant* stub = Add<HConstant>(callable.code());
8031 8033
8032 return New<HCallWithDescriptor>(stub, argument_count, callable.descriptor(), 8034 return New<HCallWithDescriptor>(stub, argument_count, callable.descriptor(),
8033 Vector<HValue*>(op_vals, arraysize(op_vals))); 8035 Vector<HValue*>(op_vals, arraysize(op_vals)),
8036 syntactic_tail_call_mode);
8034 } 8037 }
8035 8038
8036 HInstruction* HOptimizedGraphBuilder::NewCallConstantFunction( 8039 HInstruction* HOptimizedGraphBuilder::NewCallConstantFunction(
8037 Handle<JSFunction> function, int argument_count, 8040 Handle<JSFunction> function, int argument_count,
8038 TailCallMode tail_call_mode) { 8041 TailCallMode syntactic_tail_call_mode, TailCallMode tail_call_mode) {
8039 HValue* target = Add<HConstant>(function); 8042 HValue* target = Add<HConstant>(function);
8040 return New<HInvokeFunction>(target, function, argument_count, tail_call_mode); 8043 return New<HInvokeFunction>(target, function, argument_count,
8044 syntactic_tail_call_mode, tail_call_mode);
8041 } 8045 }
8042 8046
8043 8047
8044 class FunctionSorter { 8048 class FunctionSorter {
8045 public: 8049 public:
8046 explicit FunctionSorter(int index = 0, int ticks = 0, int size = 0) 8050 explicit FunctionSorter(int index = 0, int ticks = 0, int size = 0)
8047 : index_(index), ticks_(ticks), size_(size) {} 8051 : index_(index), ticks_(ticks), size_(size) {}
8048 8052
8049 int index() const { return index_; } 8053 int index() const { return index_; }
8050 int ticks() const { return ticks_; } 8054 int ticks() const { return ticks_; }
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
8181 // Trying to inline will signal that we should bailout from the 8185 // Trying to inline will signal that we should bailout from the
8182 // entire compilation by setting stack overflow on the visitor. 8186 // entire compilation by setting stack overflow on the visitor.
8183 if (HasStackOverflow()) return; 8187 if (HasStackOverflow()) return;
8184 } else { 8188 } else {
8185 // Since HWrapReceiver currently cannot actually wrap numbers and strings, 8189 // Since HWrapReceiver currently cannot actually wrap numbers and strings,
8186 // use the regular call builtin for method calls to wrap the receiver. 8190 // use the regular call builtin for method calls to wrap the receiver.
8187 // TODO(verwaest): Support creation of value wrappers directly in 8191 // TODO(verwaest): Support creation of value wrappers directly in
8188 // HWrapReceiver. 8192 // HWrapReceiver.
8189 HInstruction* call = 8193 HInstruction* call =
8190 needs_wrapping 8194 needs_wrapping
8191 ? NewCallFunction(function, argument_count, 8195 ? NewCallFunction(
8192 ConvertReceiverMode::kNotNullOrUndefined, 8196 function, argument_count, syntactic_tail_call_mode,
8193 tail_call_mode) 8197 ConvertReceiverMode::kNotNullOrUndefined, tail_call_mode)
8194 : NewCallConstantFunction(target, argument_count, tail_call_mode); 8198 : NewCallConstantFunction(target, argument_count,
8199 syntactic_tail_call_mode,
8200 tail_call_mode);
8195 PushArgumentsFromEnvironment(argument_count); 8201 PushArgumentsFromEnvironment(argument_count);
8196 AddInstruction(call); 8202 AddInstruction(call);
8197 Drop(1); // Drop the function. 8203 Drop(1); // Drop the function.
8198 if (!ast_context()->IsEffect()) Push(call); 8204 if (!ast_context()->IsEffect()) Push(call);
8199 } 8205 }
8200 8206
8201 if (current_block() != NULL) Goto(join); 8207 if (current_block() != NULL) Goto(join);
8202 set_current_block(if_false); 8208 set_current_block(if_false);
8203 } 8209 }
8204 8210
8205 // Finish up. Unconditionally deoptimize if we've handled all the maps we 8211 // Finish up. Unconditionally deoptimize if we've handled all the maps we
8206 // know about and do not want to handle ones we've never seen. Otherwise 8212 // know about and do not want to handle ones we've never seen. Otherwise
8207 // use a generic IC. 8213 // use a generic IC.
8208 if (ordered_functions == maps->length() && FLAG_deoptimize_uncommon_cases) { 8214 if (ordered_functions == maps->length() && FLAG_deoptimize_uncommon_cases) {
8209 FinishExitWithHardDeoptimization(Deoptimizer::kUnknownMapInPolymorphicCall); 8215 FinishExitWithHardDeoptimization(Deoptimizer::kUnknownMapInPolymorphicCall);
8210 } else { 8216 } else {
8211 Property* prop = expr->expression()->AsProperty(); 8217 Property* prop = expr->expression()->AsProperty();
8212 HInstruction* function = 8218 HInstruction* function =
8213 BuildNamedGeneric(LOAD, prop, prop->PropertyFeedbackSlot(), receiver, 8219 BuildNamedGeneric(LOAD, prop, prop->PropertyFeedbackSlot(), receiver,
8214 name, NULL, prop->IsUninitialized()); 8220 name, NULL, prop->IsUninitialized());
8215 AddInstruction(function); 8221 AddInstruction(function);
8216 Push(function); 8222 Push(function);
8217 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); 8223 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE);
8218 8224
8219 environment()->SetExpressionStackAt(1, function); 8225 environment()->SetExpressionStackAt(1, function);
8220 environment()->SetExpressionStackAt(0, receiver); 8226 environment()->SetExpressionStackAt(0, receiver);
8221 CHECK_ALIVE(VisitExpressions(expr->arguments())); 8227 CHECK_ALIVE(VisitExpressions(expr->arguments()));
8222 8228
8223 HInstruction* call = NewCallFunction( 8229 HInstruction* call = NewCallFunction(
8224 function, argument_count, ConvertReceiverMode::kNotNullOrUndefined, 8230 function, argument_count, syntactic_tail_call_mode,
8225 tail_call_mode); 8231 ConvertReceiverMode::kNotNullOrUndefined, tail_call_mode);
8226 8232
8227 PushArgumentsFromEnvironment(argument_count); 8233 PushArgumentsFromEnvironment(argument_count);
8228 8234
8229 Drop(1); // Function. 8235 Drop(1); // Function.
8230 8236
8231 if (join != NULL) { 8237 if (join != NULL) {
8232 AddInstruction(call); 8238 AddInstruction(call);
8233 if (!ast_context()->IsEffect()) Push(call); 8239 if (!ast_context()->IsEffect()) Push(call);
8234 Goto(join); 8240 Goto(join);
8235 } else { 8241 } else {
(...skipping 874 matching lines...) Expand 10 before | Expand all | Expand 10 after
9110 INITIALIZING_STORE); 9116 INITIALIZING_STORE);
9111 9117
9112 // Remember new length. 9118 // Remember new length.
9113 Add<HStoreNamedField>( 9119 Add<HStoreNamedField>(
9114 receiver, HObjectAccess::ForArrayLength(kind), 9120 receiver, HObjectAccess::ForArrayLength(kind),
9115 new_length, STORE_TO_INITIALIZED_ENTRY); 9121 new_length, STORE_TO_INITIALIZED_ENTRY);
9116 } 9122 }
9117 if_inline.Else(); 9123 if_inline.Else();
9118 { 9124 {
9119 Add<HPushArguments>(receiver); 9125 Add<HPushArguments>(receiver);
9120 result = AddInstruction( 9126 result = AddInstruction(NewCallConstantFunction(
9121 NewCallConstantFunction(function, 1, TailCallMode::kDisallow)); 9127 function, 1, TailCallMode::kDisallow, TailCallMode::kDisallow));
9122 if (!ast_context()->IsEffect()) Push(result); 9128 if (!ast_context()->IsEffect()) Push(result);
9123 } 9129 }
9124 if_inline.End(); 9130 if_inline.End();
9125 } 9131 }
9126 if_lengthiszero.End(); 9132 if_lengthiszero.End();
9127 } 9133 }
9128 result = ast_context()->IsEffect() ? graph()->GetConstant0() : Top(); 9134 result = ast_context()->IsEffect() ? graph()->GetConstant0() : Top();
9129 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); 9135 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
9130 if (!ast_context()->IsEffect()) Drop(1); 9136 if (!ast_context()->IsEffect()) Drop(1);
9131 ast_context()->ReturnValue(result); 9137 ast_context()->ReturnValue(result);
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
9375 if (TryInlineIndirectCall(known_function, expr, args_count_no_receiver)) { 9381 if (TryInlineIndirectCall(known_function, expr, args_count_no_receiver)) {
9376 return; 9382 return;
9377 } 9383 }
9378 } 9384 }
9379 9385
9380 TailCallMode syntactic_tail_call_mode = expr->tail_call_mode(); 9386 TailCallMode syntactic_tail_call_mode = expr->tail_call_mode();
9381 TailCallMode tail_call_mode = 9387 TailCallMode tail_call_mode =
9382 function_state()->ComputeTailCallMode(syntactic_tail_call_mode); 9388 function_state()->ComputeTailCallMode(syntactic_tail_call_mode);
9383 9389
9384 PushArgumentsFromEnvironment(arguments_count); 9390 PushArgumentsFromEnvironment(arguments_count);
9385 HInvokeFunction* call = New<HInvokeFunction>(function, known_function, 9391 HInvokeFunction* call =
9386 arguments_count, tail_call_mode); 9392 New<HInvokeFunction>(function, known_function, arguments_count,
9393 syntactic_tail_call_mode, tail_call_mode);
9387 Drop(1); // Function 9394 Drop(1); // Function
9388 ast_context()->ReturnInstruction(call, expr->id()); 9395 ast_context()->ReturnInstruction(call, expr->id());
9389 } 9396 }
9390 9397
9391 9398
9392 bool HOptimizedGraphBuilder::TryIndirectCall(Call* expr) { 9399 bool HOptimizedGraphBuilder::TryIndirectCall(Call* expr) {
9393 DCHECK(expr->expression()->IsProperty()); 9400 DCHECK(expr->expression()->IsProperty());
9394 9401
9395 if (!expr->IsMonomorphic()) { 9402 if (!expr->IsMonomorphic()) {
9396 return false; 9403 return false;
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
9773 } 9780 }
9774 if (TryInlineApiMethodCall(expr, receiver, maps)) return; 9781 if (TryInlineApiMethodCall(expr, receiver, maps)) return;
9775 9782
9776 // Wrap the receiver if necessary. 9783 // Wrap the receiver if necessary.
9777 if (NeedsWrapping(maps->first(), known_function)) { 9784 if (NeedsWrapping(maps->first(), known_function)) {
9778 // Since HWrapReceiver currently cannot actually wrap numbers and 9785 // Since HWrapReceiver currently cannot actually wrap numbers and
9779 // strings, use the regular call builtin for method calls to wrap 9786 // strings, use the regular call builtin for method calls to wrap
9780 // the receiver. 9787 // the receiver.
9781 // TODO(verwaest): Support creation of value wrappers directly in 9788 // TODO(verwaest): Support creation of value wrappers directly in
9782 // HWrapReceiver. 9789 // HWrapReceiver.
9783 call = NewCallFunction(function, argument_count, 9790 call = NewCallFunction(
9784 ConvertReceiverMode::kNotNullOrUndefined, 9791 function, argument_count, syntactic_tail_call_mode,
9785 tail_call_mode); 9792 ConvertReceiverMode::kNotNullOrUndefined, tail_call_mode);
9786 } else if (TryInlineCall(expr)) { 9793 } else if (TryInlineCall(expr)) {
9787 return; 9794 return;
9788 } else { 9795 } else {
9789 call = NewCallConstantFunction(known_function, argument_count, 9796 call =
9790 tail_call_mode); 9797 NewCallConstantFunction(known_function, argument_count,
9798 syntactic_tail_call_mode, tail_call_mode);
9791 } 9799 }
9792 9800
9793 } else { 9801 } else {
9794 ArgumentsAllowedFlag arguments_flag = ARGUMENTS_NOT_ALLOWED; 9802 ArgumentsAllowedFlag arguments_flag = ARGUMENTS_NOT_ALLOWED;
9795 if (CanBeFunctionApplyArguments(expr) && expr->is_uninitialized()) { 9803 if (CanBeFunctionApplyArguments(expr) && expr->is_uninitialized()) {
9796 // We have to use EAGER deoptimization here because Deoptimizer::SOFT 9804 // We have to use EAGER deoptimization here because Deoptimizer::SOFT
9797 // gets ignored by the always-opt flag, which leads to incorrect code. 9805 // gets ignored by the always-opt flag, which leads to incorrect code.
9798 Add<HDeoptimize>( 9806 Add<HDeoptimize>(
9799 Deoptimizer::kInsufficientTypeFeedbackForCallWithArguments, 9807 Deoptimizer::kInsufficientTypeFeedbackForCallWithArguments,
9800 Deoptimizer::EAGER); 9808 Deoptimizer::EAGER);
9801 arguments_flag = ARGUMENTS_FAKED; 9809 arguments_flag = ARGUMENTS_FAKED;
9802 } 9810 }
9803 9811
9804 // Push the function under the receiver. 9812 // Push the function under the receiver.
9805 environment()->SetExpressionStackAt(0, function); 9813 environment()->SetExpressionStackAt(0, function);
9806 Push(receiver); 9814 Push(receiver);
9807 9815
9808 CHECK_ALIVE(VisitExpressions(expr->arguments(), arguments_flag)); 9816 CHECK_ALIVE(VisitExpressions(expr->arguments(), arguments_flag));
9809 call = NewCallFunction(function, argument_count, 9817 call = NewCallFunction(function, argument_count, syntactic_tail_call_mode,
9810 ConvertReceiverMode::kNotNullOrUndefined, 9818 ConvertReceiverMode::kNotNullOrUndefined,
9811 tail_call_mode); 9819 tail_call_mode);
9812 } 9820 }
9813 PushArgumentsFromEnvironment(argument_count); 9821 PushArgumentsFromEnvironment(argument_count);
9814 9822
9815 } else { 9823 } else {
9816 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 9824 VariableProxy* proxy = expr->expression()->AsVariableProxy();
9817 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { 9825 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) {
9818 return Bailout(kPossibleDirectCallToEval); 9826 return Bailout(kPossibleDirectCallToEval);
9819 } 9827 }
(...skipping 29 matching lines...) Expand all
9849 PrintF("\n"); 9857 PrintF("\n");
9850 } 9858 }
9851 return; 9859 return;
9852 } 9860 }
9853 if (TryInlineApiFunctionCall(expr, receiver)) return; 9861 if (TryInlineApiFunctionCall(expr, receiver)) return;
9854 if (TryHandleArrayCall(expr, function)) return; 9862 if (TryHandleArrayCall(expr, function)) return;
9855 if (TryInlineCall(expr)) return; 9863 if (TryInlineCall(expr)) return;
9856 9864
9857 PushArgumentsFromEnvironment(argument_count); 9865 PushArgumentsFromEnvironment(argument_count);
9858 call = NewCallConstantFunction(expr->target(), argument_count, 9866 call = NewCallConstantFunction(expr->target(), argument_count,
9859 tail_call_mode); 9867 syntactic_tail_call_mode, tail_call_mode);
9860 } else { 9868 } else {
9861 PushArgumentsFromEnvironment(argument_count); 9869 PushArgumentsFromEnvironment(argument_count);
9862 if (expr->is_uninitialized() && 9870 if (expr->is_uninitialized() &&
9863 expr->IsUsingCallFeedbackICSlot(isolate())) { 9871 expr->IsUsingCallFeedbackICSlot(isolate())) {
9864 // We've never seen this call before, so let's have Crankshaft learn 9872 // We've never seen this call before, so let's have Crankshaft learn
9865 // through the type vector. 9873 // through the type vector.
9866 call = NewCallFunctionViaIC(function, argument_count, 9874 call = NewCallFunctionViaIC(function, argument_count,
9875 syntactic_tail_call_mode,
9867 ConvertReceiverMode::kNullOrUndefined, 9876 ConvertReceiverMode::kNullOrUndefined,
9868 tail_call_mode, expr->CallFeedbackICSlot()); 9877 tail_call_mode, expr->CallFeedbackICSlot());
9869 } else { 9878 } else {
9870 call = NewCallFunction(function, argument_count, 9879 call = NewCallFunction(
9871 ConvertReceiverMode::kNullOrUndefined, 9880 function, argument_count, syntactic_tail_call_mode,
9872 tail_call_mode); 9881 ConvertReceiverMode::kNullOrUndefined, tail_call_mode);
9873 } 9882 }
9874 } 9883 }
9875 } 9884 }
9876 9885
9877 Drop(1); // Drop the function. 9886 Drop(1); // Drop the function.
9878 return ast_context()->ReturnInstruction(call, expr->id()); 9887 return ast_context()->ReturnInstruction(call, expr->id());
9879 } 9888 }
9880 9889
9881 9890
9882 void HOptimizedGraphBuilder::BuildInlinedCallArray( 9891 void HOptimizedGraphBuilder::BuildInlinedCallArray(
(...skipping 3631 matching lines...) Expand 10 before | Expand all | Expand 10 after
13514 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 13523 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
13515 } 13524 }
13516 13525
13517 #ifdef DEBUG 13526 #ifdef DEBUG
13518 graph_->Verify(false); // No full verify. 13527 graph_->Verify(false); // No full verify.
13519 #endif 13528 #endif
13520 } 13529 }
13521 13530
13522 } // namespace internal 13531 } // namespace internal
13523 } // namespace v8 13532 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698