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

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

Issue 1814433002: Revert of [crankshaft] Fixing ES6 tail call elimination. (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 5495 matching lines...) Expand 10 before | Expand all | Expand 10 after
5506 // Use the fast case closure allocation code that allocates in new 5506 // Use the fast case closure allocation code that allocates in new
5507 // space for nested functions that don't need literals cloning. 5507 // space for nested functions that don't need literals cloning.
5508 HConstant* shared_info_value = Add<HConstant>(shared_info); 5508 HConstant* shared_info_value = Add<HConstant>(shared_info);
5509 HInstruction* instr; 5509 HInstruction* instr;
5510 if (!expr->pretenure() && shared_info->num_literals() == 0) { 5510 if (!expr->pretenure() && shared_info->num_literals() == 0) {
5511 FastNewClosureStub stub(isolate(), shared_info->language_mode(), 5511 FastNewClosureStub stub(isolate(), shared_info->language_mode(),
5512 shared_info->kind()); 5512 shared_info->kind());
5513 FastNewClosureDescriptor descriptor(isolate()); 5513 FastNewClosureDescriptor descriptor(isolate());
5514 HValue* values[] = {context(), shared_info_value}; 5514 HValue* values[] = {context(), shared_info_value};
5515 HConstant* stub_value = Add<HConstant>(stub.GetCode()); 5515 HConstant* stub_value = Add<HConstant>(stub.GetCode());
5516 instr = New<HCallWithDescriptor>( 5516 instr = New<HCallWithDescriptor>(stub_value, 0, descriptor,
5517 stub_value, 0, descriptor, Vector<HValue*>(values, arraysize(values))); 5517 Vector<HValue*>(values, arraysize(values)),
5518 NORMAL_CALL);
5518 } else { 5519 } else {
5519 Add<HPushArguments>(shared_info_value); 5520 Add<HPushArguments>(shared_info_value);
5520 Runtime::FunctionId function_id = 5521 Runtime::FunctionId function_id =
5521 expr->pretenure() ? Runtime::kNewClosure_Tenured : Runtime::kNewClosure; 5522 expr->pretenure() ? Runtime::kNewClosure_Tenured : Runtime::kNewClosure;
5522 instr = New<HCallRuntime>(Runtime::FunctionForId(function_id), 1); 5523 instr = New<HCallRuntime>(Runtime::FunctionForId(function_id), 1);
5523 } 5524 }
5524 return ast_context()->ReturnInstruction(instr, expr->id()); 5525 return ast_context()->ReturnInstruction(instr, expr->id());
5525 } 5526 }
5526 5527
5527 5528
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
5788 5789
5789 void HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { 5790 void HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
5790 DCHECK(!HasStackOverflow()); 5791 DCHECK(!HasStackOverflow());
5791 DCHECK(current_block() != NULL); 5792 DCHECK(current_block() != NULL);
5792 DCHECK(current_block()->HasPredecessor()); 5793 DCHECK(current_block()->HasPredecessor());
5793 Callable callable = CodeFactory::FastCloneRegExp(isolate()); 5794 Callable callable = CodeFactory::FastCloneRegExp(isolate());
5794 HValue* values[] = { 5795 HValue* values[] = {
5795 context(), AddThisFunction(), Add<HConstant>(expr->literal_index()), 5796 context(), AddThisFunction(), Add<HConstant>(expr->literal_index()),
5796 Add<HConstant>(expr->pattern()), Add<HConstant>(expr->flags())}; 5797 Add<HConstant>(expr->pattern()), Add<HConstant>(expr->flags())};
5797 HConstant* stub_value = Add<HConstant>(callable.code()); 5798 HConstant* stub_value = Add<HConstant>(callable.code());
5798 HInstruction* instr = 5799 HInstruction* instr = New<HCallWithDescriptor>(
5799 New<HCallWithDescriptor>(stub_value, 0, callable.descriptor(), 5800 stub_value, 0, callable.descriptor(),
5800 Vector<HValue*>(values, arraysize(values))); 5801 Vector<HValue*>(values, arraysize(values)), NORMAL_CALL);
5801 return ast_context()->ReturnInstruction(instr, expr->id()); 5802 return ast_context()->ReturnInstruction(instr, expr->id());
5802 } 5803 }
5803 5804
5804 5805
5805 static bool CanInlinePropertyAccess(Handle<Map> map) { 5806 static bool CanInlinePropertyAccess(Handle<Map> map) {
5806 if (map->instance_type() == HEAP_NUMBER_TYPE) return true; 5807 if (map->instance_type() == HEAP_NUMBER_TYPE) return true;
5807 if (map->instance_type() < FIRST_NONSTRING_TYPE) return true; 5808 if (map->instance_type() < FIRST_NONSTRING_TYPE) return true;
5808 return map->IsJSObjectMap() && !map->is_dictionary_map() && 5809 return map->IsJSObjectMap() && !map->is_dictionary_map() &&
5809 !map->has_named_interceptor() && 5810 !map->has_named_interceptor() &&
5810 // TODO(verwaest): Whitelist contexts to which we have access. 5811 // TODO(verwaest): Whitelist contexts to which we have access.
(...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after
6575 int argument_count = 1; 6576 int argument_count = 1;
6576 if (!info->IsLoad()) { 6577 if (!info->IsLoad()) {
6577 argument_count = 2; 6578 argument_count = 2;
6578 Push(value); 6579 Push(value);
6579 } 6580 }
6580 6581
6581 if (info->accessor()->IsJSFunction() && 6582 if (info->accessor()->IsJSFunction() &&
6582 info->NeedsWrappingFor(Handle<JSFunction>::cast(info->accessor()))) { 6583 info->NeedsWrappingFor(Handle<JSFunction>::cast(info->accessor()))) {
6583 HValue* function = Add<HConstant>(info->accessor()); 6584 HValue* function = Add<HConstant>(info->accessor());
6584 PushArgumentsFromEnvironment(argument_count); 6585 PushArgumentsFromEnvironment(argument_count);
6585 return NewCallFunction(function, argument_count, TailCallMode::kDisallow, 6586 return NewCallFunction(function, argument_count,
6586 ConvertReceiverMode::kNotNullOrUndefined, 6587 ConvertReceiverMode::kNotNullOrUndefined,
6587 TailCallMode::kDisallow); 6588 TailCallMode::kDisallow);
6588 } else if (FLAG_inline_accessors && can_inline_accessor) { 6589 } else if (FLAG_inline_accessors && can_inline_accessor) {
6589 bool success = info->IsLoad() 6590 bool success = info->IsLoad()
6590 ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id) 6591 ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id)
6591 : TryInlineSetter( 6592 : TryInlineSetter(
6592 info->accessor(), info->map(), ast_id, return_id, value); 6593 info->accessor(), info->map(), ast_id, return_id, value);
6593 if (success || HasStackOverflow()) return NULL; 6594 if (success || HasStackOverflow()) return NULL;
6594 } 6595 }
6595 6596
6596 PushArgumentsFromEnvironment(argument_count); 6597 PushArgumentsFromEnvironment(argument_count);
6597 if (!info->accessor()->IsJSFunction()) { 6598 if (!info->accessor()->IsJSFunction()) {
6598 Bailout(kInliningBailedOut); 6599 Bailout(kInliningBailedOut);
6599 return nullptr; 6600 return nullptr;
6600 } 6601 }
6601 return NewCallConstantFunction(Handle<JSFunction>::cast(info->accessor()), 6602 return NewCallConstantFunction(Handle<JSFunction>::cast(info->accessor()),
6602 argument_count, TailCallMode::kDisallow, 6603 argument_count, TailCallMode::kDisallow);
6603 TailCallMode::kDisallow);
6604 } 6604 }
6605 6605
6606 DCHECK(info->IsDataConstant()); 6606 DCHECK(info->IsDataConstant());
6607 if (info->IsLoad()) { 6607 if (info->IsLoad()) {
6608 return New<HConstant>(info->constant()); 6608 return New<HConstant>(info->constant());
6609 } else { 6609 } else {
6610 return New<HCheckValue>(value, Handle<JSFunction>::cast(info->constant())); 6610 return New<HCheckValue>(value, Handle<JSFunction>::cast(info->constant()));
6611 } 6611 }
6612 } 6612 }
6613 6613
(...skipping 1378 matching lines...) Expand 10 before | Expand all | Expand 10 after
7992 7992
7993 void HOptimizedGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder, 7993 void HOptimizedGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder,
7994 Handle<Map> receiver_map) { 7994 Handle<Map> receiver_map) {
7995 if (!holder.is_null()) { 7995 if (!holder.is_null()) {
7996 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype())); 7996 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype()));
7997 BuildCheckPrototypeMaps(prototype, holder); 7997 BuildCheckPrototypeMaps(prototype, holder);
7998 } 7998 }
7999 } 7999 }
8000 8000
8001 HInstruction* HOptimizedGraphBuilder::NewCallFunction( 8001 HInstruction* HOptimizedGraphBuilder::NewCallFunction(
8002 HValue* function, int argument_count, TailCallMode syntactic_tail_call_mode, 8002 HValue* function, int argument_count, ConvertReceiverMode convert_mode,
8003 ConvertReceiverMode convert_mode, TailCallMode tail_call_mode) { 8003 TailCallMode tail_call_mode) {
8004 HValue* arity = Add<HConstant>(argument_count - 1); 8004 HValue* arity = Add<HConstant>(argument_count - 1);
8005 8005
8006 HValue* op_vals[] = {context(), function, arity}; 8006 HValue* op_vals[] = {context(), function, arity};
8007 8007
8008 Callable callable = 8008 Callable callable =
8009 CodeFactory::Call(isolate(), convert_mode, tail_call_mode); 8009 CodeFactory::Call(isolate(), convert_mode, tail_call_mode);
8010 HConstant* stub = Add<HConstant>(callable.code()); 8010 HConstant* stub = Add<HConstant>(callable.code());
8011 8011
8012 return New<HCallWithDescriptor>(stub, argument_count, callable.descriptor(), 8012 return New<HCallWithDescriptor>(stub, argument_count, callable.descriptor(),
8013 Vector<HValue*>(op_vals, arraysize(op_vals)), 8013 Vector<HValue*>(op_vals, arraysize(op_vals)));
8014 syntactic_tail_call_mode);
8015 } 8014 }
8016 8015
8017 HInstruction* HOptimizedGraphBuilder::NewCallFunctionViaIC( 8016 HInstruction* HOptimizedGraphBuilder::NewCallFunctionViaIC(
8018 HValue* function, int argument_count, TailCallMode syntactic_tail_call_mode, 8017 HValue* function, int argument_count, ConvertReceiverMode convert_mode,
8019 ConvertReceiverMode convert_mode, TailCallMode tail_call_mode, 8018 TailCallMode tail_call_mode, FeedbackVectorSlot slot) {
8020 FeedbackVectorSlot slot) {
8021 int arity = argument_count - 1; 8019 int arity = argument_count - 1;
8022 Handle<TypeFeedbackVector> vector(current_feedback_vector(), isolate()); 8020 Handle<TypeFeedbackVector> vector(current_feedback_vector(), isolate());
8023 HValue* index_val = Add<HConstant>(vector->GetIndex(slot)); 8021 HValue* index_val = Add<HConstant>(vector->GetIndex(slot));
8024 HValue* vector_val = Add<HConstant>(vector); 8022 HValue* vector_val = Add<HConstant>(vector);
8025 8023
8026 HValue* op_vals[] = {context(), function, index_val, vector_val}; 8024 HValue* op_vals[] = {context(), function, index_val, vector_val};
8027 8025
8028 Callable callable = CodeFactory::CallICInOptimizedCode( 8026 Callable callable = CodeFactory::CallICInOptimizedCode(
8029 isolate(), arity, ConvertReceiverMode::kNullOrUndefined, tail_call_mode); 8027 isolate(), arity, ConvertReceiverMode::kNullOrUndefined, tail_call_mode);
8030 HConstant* stub = Add<HConstant>(callable.code()); 8028 HConstant* stub = Add<HConstant>(callable.code());
8031 8029
8032 return New<HCallWithDescriptor>(stub, argument_count, callable.descriptor(), 8030 return New<HCallWithDescriptor>(stub, argument_count, callable.descriptor(),
8033 Vector<HValue*>(op_vals, arraysize(op_vals)), 8031 Vector<HValue*>(op_vals, arraysize(op_vals)));
8034 syntactic_tail_call_mode);
8035 } 8032 }
8036 8033
8037 HInstruction* HOptimizedGraphBuilder::NewCallConstantFunction( 8034 HInstruction* HOptimizedGraphBuilder::NewCallConstantFunction(
8038 Handle<JSFunction> function, int argument_count, 8035 Handle<JSFunction> function, int argument_count,
8039 TailCallMode syntactic_tail_call_mode, TailCallMode tail_call_mode) { 8036 TailCallMode tail_call_mode) {
8040 HValue* target = Add<HConstant>(function); 8037 HValue* target = Add<HConstant>(function);
8041 return New<HInvokeFunction>(target, function, argument_count, 8038 return New<HInvokeFunction>(target, function, argument_count, tail_call_mode);
8042 syntactic_tail_call_mode, tail_call_mode);
8043 } 8039 }
8044 8040
8045 8041
8046 class FunctionSorter { 8042 class FunctionSorter {
8047 public: 8043 public:
8048 explicit FunctionSorter(int index = 0, int ticks = 0, int size = 0) 8044 explicit FunctionSorter(int index = 0, int ticks = 0, int size = 0)
8049 : index_(index), ticks_(ticks), size_(size) {} 8045 : index_(index), ticks_(ticks), size_(size) {}
8050 8046
8051 int index() const { return index_; } 8047 int index() const { return index_; }
8052 int ticks() const { return ticks_; } 8048 int ticks() const { return ticks_; }
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
8183 // Trying to inline will signal that we should bailout from the 8179 // Trying to inline will signal that we should bailout from the
8184 // entire compilation by setting stack overflow on the visitor. 8180 // entire compilation by setting stack overflow on the visitor.
8185 if (HasStackOverflow()) return; 8181 if (HasStackOverflow()) return;
8186 } else { 8182 } else {
8187 // Since HWrapReceiver currently cannot actually wrap numbers and strings, 8183 // Since HWrapReceiver currently cannot actually wrap numbers and strings,
8188 // use the regular call builtin for method calls to wrap the receiver. 8184 // use the regular call builtin for method calls to wrap the receiver.
8189 // TODO(verwaest): Support creation of value wrappers directly in 8185 // TODO(verwaest): Support creation of value wrappers directly in
8190 // HWrapReceiver. 8186 // HWrapReceiver.
8191 HInstruction* call = 8187 HInstruction* call =
8192 needs_wrapping 8188 needs_wrapping
8193 ? NewCallFunction( 8189 ? NewCallFunction(function, argument_count,
8194 function, argument_count, syntactic_tail_call_mode, 8190 ConvertReceiverMode::kNotNullOrUndefined,
8195 ConvertReceiverMode::kNotNullOrUndefined, tail_call_mode) 8191 tail_call_mode)
8196 : NewCallConstantFunction(target, argument_count, 8192 : NewCallConstantFunction(target, argument_count, tail_call_mode);
8197 syntactic_tail_call_mode,
8198 tail_call_mode);
8199 PushArgumentsFromEnvironment(argument_count); 8193 PushArgumentsFromEnvironment(argument_count);
8200 AddInstruction(call); 8194 AddInstruction(call);
8201 Drop(1); // Drop the function. 8195 Drop(1); // Drop the function.
8202 if (!ast_context()->IsEffect()) Push(call); 8196 if (!ast_context()->IsEffect()) Push(call);
8203 } 8197 }
8204 8198
8205 if (current_block() != NULL) Goto(join); 8199 if (current_block() != NULL) Goto(join);
8206 set_current_block(if_false); 8200 set_current_block(if_false);
8207 } 8201 }
8208 8202
8209 // Finish up. Unconditionally deoptimize if we've handled all the maps we 8203 // Finish up. Unconditionally deoptimize if we've handled all the maps we
8210 // know about and do not want to handle ones we've never seen. Otherwise 8204 // know about and do not want to handle ones we've never seen. Otherwise
8211 // use a generic IC. 8205 // use a generic IC.
8212 if (ordered_functions == maps->length() && FLAG_deoptimize_uncommon_cases) { 8206 if (ordered_functions == maps->length() && FLAG_deoptimize_uncommon_cases) {
8213 FinishExitWithHardDeoptimization(Deoptimizer::kUnknownMapInPolymorphicCall); 8207 FinishExitWithHardDeoptimization(Deoptimizer::kUnknownMapInPolymorphicCall);
8214 } else { 8208 } else {
8215 Property* prop = expr->expression()->AsProperty(); 8209 Property* prop = expr->expression()->AsProperty();
8216 HInstruction* function = 8210 HInstruction* function =
8217 BuildNamedGeneric(LOAD, prop, prop->PropertyFeedbackSlot(), receiver, 8211 BuildNamedGeneric(LOAD, prop, prop->PropertyFeedbackSlot(), receiver,
8218 name, NULL, prop->IsUninitialized()); 8212 name, NULL, prop->IsUninitialized());
8219 AddInstruction(function); 8213 AddInstruction(function);
8220 Push(function); 8214 Push(function);
8221 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); 8215 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE);
8222 8216
8223 environment()->SetExpressionStackAt(1, function); 8217 environment()->SetExpressionStackAt(1, function);
8224 environment()->SetExpressionStackAt(0, receiver); 8218 environment()->SetExpressionStackAt(0, receiver);
8225 CHECK_ALIVE(VisitExpressions(expr->arguments())); 8219 CHECK_ALIVE(VisitExpressions(expr->arguments()));
8226 8220
8227 HInstruction* call = NewCallFunction( 8221 HInstruction* call = NewCallFunction(
8228 function, argument_count, syntactic_tail_call_mode, 8222 function, argument_count, ConvertReceiverMode::kNotNullOrUndefined,
8229 ConvertReceiverMode::kNotNullOrUndefined, tail_call_mode); 8223 tail_call_mode);
8230 8224
8231 PushArgumentsFromEnvironment(argument_count); 8225 PushArgumentsFromEnvironment(argument_count);
8232 8226
8233 Drop(1); // Function. 8227 Drop(1); // Function.
8234 8228
8235 if (join != NULL) { 8229 if (join != NULL) {
8236 AddInstruction(call); 8230 AddInstruction(call);
8237 if (!ast_context()->IsEffect()) Push(call); 8231 if (!ast_context()->IsEffect()) Push(call);
8238 Goto(join); 8232 Goto(join);
8239 } else { 8233 } else {
(...skipping 865 matching lines...) Expand 10 before | Expand all | Expand 10 after
9105 INITIALIZING_STORE); 9099 INITIALIZING_STORE);
9106 9100
9107 // Remember new length. 9101 // Remember new length.
9108 Add<HStoreNamedField>( 9102 Add<HStoreNamedField>(
9109 receiver, HObjectAccess::ForArrayLength(kind), 9103 receiver, HObjectAccess::ForArrayLength(kind),
9110 new_length, STORE_TO_INITIALIZED_ENTRY); 9104 new_length, STORE_TO_INITIALIZED_ENTRY);
9111 } 9105 }
9112 if_inline.Else(); 9106 if_inline.Else();
9113 { 9107 {
9114 Add<HPushArguments>(receiver); 9108 Add<HPushArguments>(receiver);
9115 result = AddInstruction(NewCallConstantFunction( 9109 result = AddInstruction(
9116 function, 1, TailCallMode::kDisallow, TailCallMode::kDisallow)); 9110 NewCallConstantFunction(function, 1, TailCallMode::kDisallow));
9117 if (!ast_context()->IsEffect()) Push(result); 9111 if (!ast_context()->IsEffect()) Push(result);
9118 } 9112 }
9119 if_inline.End(); 9113 if_inline.End();
9120 } 9114 }
9121 if_lengthiszero.End(); 9115 if_lengthiszero.End();
9122 } 9116 }
9123 result = ast_context()->IsEffect() ? graph()->GetConstant0() : Top(); 9117 result = ast_context()->IsEffect() ? graph()->GetConstant0() : Top();
9124 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); 9118 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
9125 if (!ast_context()->IsEffect()) Drop(1); 9119 if (!ast_context()->IsEffect()) Drop(1);
9126 ast_context()->ReturnValue(result); 9120 ast_context()->ReturnValue(result);
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
9370 if (TryInlineIndirectCall(known_function, expr, args_count_no_receiver)) { 9364 if (TryInlineIndirectCall(known_function, expr, args_count_no_receiver)) {
9371 return; 9365 return;
9372 } 9366 }
9373 } 9367 }
9374 9368
9375 TailCallMode syntactic_tail_call_mode = expr->tail_call_mode(); 9369 TailCallMode syntactic_tail_call_mode = expr->tail_call_mode();
9376 TailCallMode tail_call_mode = 9370 TailCallMode tail_call_mode =
9377 function_state()->ComputeTailCallMode(syntactic_tail_call_mode); 9371 function_state()->ComputeTailCallMode(syntactic_tail_call_mode);
9378 9372
9379 PushArgumentsFromEnvironment(arguments_count); 9373 PushArgumentsFromEnvironment(arguments_count);
9380 HInvokeFunction* call = 9374 HInvokeFunction* call = New<HInvokeFunction>(function, known_function,
9381 New<HInvokeFunction>(function, known_function, arguments_count, 9375 arguments_count, tail_call_mode);
9382 syntactic_tail_call_mode, tail_call_mode);
9383 Drop(1); // Function 9376 Drop(1); // Function
9384 ast_context()->ReturnInstruction(call, expr->id()); 9377 ast_context()->ReturnInstruction(call, expr->id());
9385 } 9378 }
9386 9379
9387 9380
9388 bool HOptimizedGraphBuilder::TryIndirectCall(Call* expr) { 9381 bool HOptimizedGraphBuilder::TryIndirectCall(Call* expr) {
9389 DCHECK(expr->expression()->IsProperty()); 9382 DCHECK(expr->expression()->IsProperty());
9390 9383
9391 if (!expr->IsMonomorphic()) { 9384 if (!expr->IsMonomorphic()) {
9392 return false; 9385 return false;
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
9769 } 9762 }
9770 if (TryInlineApiMethodCall(expr, receiver, maps)) return; 9763 if (TryInlineApiMethodCall(expr, receiver, maps)) return;
9771 9764
9772 // Wrap the receiver if necessary. 9765 // Wrap the receiver if necessary.
9773 if (NeedsWrapping(maps->first(), known_function)) { 9766 if (NeedsWrapping(maps->first(), known_function)) {
9774 // Since HWrapReceiver currently cannot actually wrap numbers and 9767 // Since HWrapReceiver currently cannot actually wrap numbers and
9775 // strings, use the regular call builtin for method calls to wrap 9768 // strings, use the regular call builtin for method calls to wrap
9776 // the receiver. 9769 // the receiver.
9777 // TODO(verwaest): Support creation of value wrappers directly in 9770 // TODO(verwaest): Support creation of value wrappers directly in
9778 // HWrapReceiver. 9771 // HWrapReceiver.
9779 call = NewCallFunction( 9772 call = NewCallFunction(function, argument_count,
9780 function, argument_count, syntactic_tail_call_mode, 9773 ConvertReceiverMode::kNotNullOrUndefined,
9781 ConvertReceiverMode::kNotNullOrUndefined, tail_call_mode); 9774 tail_call_mode);
9782 } else if (TryInlineCall(expr)) { 9775 } else if (TryInlineCall(expr)) {
9783 return; 9776 return;
9784 } else { 9777 } else {
9785 call = 9778 call = NewCallConstantFunction(known_function, argument_count,
9786 NewCallConstantFunction(known_function, argument_count, 9779 tail_call_mode);
9787 syntactic_tail_call_mode, tail_call_mode);
9788 } 9780 }
9789 9781
9790 } else { 9782 } else {
9791 ArgumentsAllowedFlag arguments_flag = ARGUMENTS_NOT_ALLOWED; 9783 ArgumentsAllowedFlag arguments_flag = ARGUMENTS_NOT_ALLOWED;
9792 if (CanBeFunctionApplyArguments(expr) && expr->is_uninitialized()) { 9784 if (CanBeFunctionApplyArguments(expr) && expr->is_uninitialized()) {
9793 // We have to use EAGER deoptimization here because Deoptimizer::SOFT 9785 // We have to use EAGER deoptimization here because Deoptimizer::SOFT
9794 // gets ignored by the always-opt flag, which leads to incorrect code. 9786 // gets ignored by the always-opt flag, which leads to incorrect code.
9795 Add<HDeoptimize>( 9787 Add<HDeoptimize>(
9796 Deoptimizer::kInsufficientTypeFeedbackForCallWithArguments, 9788 Deoptimizer::kInsufficientTypeFeedbackForCallWithArguments,
9797 Deoptimizer::EAGER); 9789 Deoptimizer::EAGER);
9798 arguments_flag = ARGUMENTS_FAKED; 9790 arguments_flag = ARGUMENTS_FAKED;
9799 } 9791 }
9800 9792
9801 // Push the function under the receiver. 9793 // Push the function under the receiver.
9802 environment()->SetExpressionStackAt(0, function); 9794 environment()->SetExpressionStackAt(0, function);
9803 Push(receiver); 9795 Push(receiver);
9804 9796
9805 CHECK_ALIVE(VisitExpressions(expr->arguments(), arguments_flag)); 9797 CHECK_ALIVE(VisitExpressions(expr->arguments(), arguments_flag));
9806 call = NewCallFunction(function, argument_count, syntactic_tail_call_mode, 9798 call = NewCallFunction(function, argument_count,
9807 ConvertReceiverMode::kNotNullOrUndefined, 9799 ConvertReceiverMode::kNotNullOrUndefined,
9808 tail_call_mode); 9800 tail_call_mode);
9809 } 9801 }
9810 PushArgumentsFromEnvironment(argument_count); 9802 PushArgumentsFromEnvironment(argument_count);
9811 9803
9812 } else { 9804 } else {
9813 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 9805 VariableProxy* proxy = expr->expression()->AsVariableProxy();
9814 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { 9806 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) {
9815 return Bailout(kPossibleDirectCallToEval); 9807 return Bailout(kPossibleDirectCallToEval);
9816 } 9808 }
(...skipping 29 matching lines...) Expand all
9846 PrintF("\n"); 9838 PrintF("\n");
9847 } 9839 }
9848 return; 9840 return;
9849 } 9841 }
9850 if (TryInlineApiFunctionCall(expr, receiver)) return; 9842 if (TryInlineApiFunctionCall(expr, receiver)) return;
9851 if (TryHandleArrayCall(expr, function)) return; 9843 if (TryHandleArrayCall(expr, function)) return;
9852 if (TryInlineCall(expr)) return; 9844 if (TryInlineCall(expr)) return;
9853 9845
9854 PushArgumentsFromEnvironment(argument_count); 9846 PushArgumentsFromEnvironment(argument_count);
9855 call = NewCallConstantFunction(expr->target(), argument_count, 9847 call = NewCallConstantFunction(expr->target(), argument_count,
9856 syntactic_tail_call_mode, tail_call_mode); 9848 tail_call_mode);
9857 } else { 9849 } else {
9858 PushArgumentsFromEnvironment(argument_count); 9850 PushArgumentsFromEnvironment(argument_count);
9859 if (expr->is_uninitialized() && 9851 if (expr->is_uninitialized() &&
9860 expr->IsUsingCallFeedbackICSlot(isolate())) { 9852 expr->IsUsingCallFeedbackICSlot(isolate())) {
9861 // We've never seen this call before, so let's have Crankshaft learn 9853 // We've never seen this call before, so let's have Crankshaft learn
9862 // through the type vector. 9854 // through the type vector.
9863 call = NewCallFunctionViaIC(function, argument_count, 9855 call = NewCallFunctionViaIC(function, argument_count,
9864 syntactic_tail_call_mode,
9865 ConvertReceiverMode::kNullOrUndefined, 9856 ConvertReceiverMode::kNullOrUndefined,
9866 tail_call_mode, expr->CallFeedbackICSlot()); 9857 tail_call_mode, expr->CallFeedbackICSlot());
9867 } else { 9858 } else {
9868 call = NewCallFunction( 9859 call = NewCallFunction(function, argument_count,
9869 function, argument_count, syntactic_tail_call_mode, 9860 ConvertReceiverMode::kNullOrUndefined,
9870 ConvertReceiverMode::kNullOrUndefined, tail_call_mode); 9861 tail_call_mode);
9871 } 9862 }
9872 } 9863 }
9873 } 9864 }
9874 9865
9875 Drop(1); // Drop the function. 9866 Drop(1); // Drop the function.
9876 return ast_context()->ReturnInstruction(call, expr->id()); 9867 return ast_context()->ReturnInstruction(call, expr->id());
9877 } 9868 }
9878 9869
9879 9870
9880 void HOptimizedGraphBuilder::BuildInlinedCallArray( 9871 void HOptimizedGraphBuilder::BuildInlinedCallArray(
(...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after
10493 // The callee and the receiver both have to be pushed onto the operand stack 10484 // The callee and the receiver both have to be pushed onto the operand stack
10494 // before arguments are being evaluated. 10485 // before arguments are being evaluated.
10495 HValue* function = AddLoadJSBuiltin(expr->context_index()); 10486 HValue* function = AddLoadJSBuiltin(expr->context_index());
10496 HValue* receiver = graph()->GetConstantUndefined(); 10487 HValue* receiver = graph()->GetConstantUndefined();
10497 Push(function); 10488 Push(function);
10498 Push(receiver); 10489 Push(receiver);
10499 10490
10500 int argument_count = expr->arguments()->length() + 1; // Count receiver. 10491 int argument_count = expr->arguments()->length() + 1; // Count receiver.
10501 CHECK_ALIVE(VisitExpressions(expr->arguments())); 10492 CHECK_ALIVE(VisitExpressions(expr->arguments()));
10502 PushArgumentsFromEnvironment(argument_count); 10493 PushArgumentsFromEnvironment(argument_count);
10503 HInstruction* call = NewCallFunction( 10494 HInstruction* call = NewCallFunction(function, argument_count,
10504 function, argument_count, TailCallMode::kDisallow, 10495 ConvertReceiverMode::kNullOrUndefined,
10505 ConvertReceiverMode::kNullOrUndefined, TailCallMode::kDisallow); 10496 TailCallMode::kDisallow);
10506 Drop(1); // Function 10497 Drop(1); // Function
10507 return ast_context()->ReturnInstruction(call, expr->id()); 10498 return ast_context()->ReturnInstruction(call, expr->id());
10508 } 10499 }
10509 10500
10510 const Runtime::Function* function = expr->function(); 10501 const Runtime::Function* function = expr->function();
10511 DCHECK(function != NULL); 10502 DCHECK(function != NULL);
10512 switch (function->function_id) { 10503 switch (function->function_id) {
10513 #define CALL_INTRINSIC_GENERATOR(Name) \ 10504 #define CALL_INTRINSIC_GENERATOR(Name) \
10514 case Runtime::kInline##Name: \ 10505 case Runtime::kInline##Name: \
10515 return Generate##Name(expr); 10506 return Generate##Name(expr);
(...skipping 3006 matching lines...) Expand 10 before | Expand all | Expand 10 after
13522 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 13513 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
13523 } 13514 }
13524 13515
13525 #ifdef DEBUG 13516 #ifdef DEBUG
13526 graph_->Verify(false); // No full verify. 13517 graph_->Verify(false); // No full verify.
13527 #endif 13518 #endif
13528 } 13519 }
13529 13520
13530 } // namespace internal 13521 } // namespace internal
13531 } // namespace v8 13522 } // 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