OLD | NEW |
---|---|
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 3829 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3840 instruction->DeleteAndReplaceWith(instruction->RedefinedOperand()); | 3840 instruction->DeleteAndReplaceWith(instruction->RedefinedOperand()); |
3841 } else { | 3841 } else { |
3842 instruction->ReplaceAllUsesWith(instruction->ActualValue()); | 3842 instruction->ReplaceAllUsesWith(instruction->ActualValue()); |
3843 } | 3843 } |
3844 } | 3844 } |
3845 } | 3845 } |
3846 } | 3846 } |
3847 } | 3847 } |
3848 | 3848 |
3849 | 3849 |
3850 template <class Instruction> | 3850 void HOptimizedGraphBuilder::PushArgumentsFromEnvironment(int count) { |
3851 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) { | |
3852 int count = call->argument_count(); | |
3853 ZoneList<HValue*> arguments(count, zone()); | 3851 ZoneList<HValue*> arguments(count, zone()); |
3854 for (int i = 0; i < count; ++i) { | 3852 for (int i = 0; i < count; ++i) { |
3855 arguments.Add(Pop(), zone()); | 3853 arguments.Add(Pop(), zone()); |
3856 } | 3854 } |
3857 | 3855 |
3858 while (!arguments.is_empty()) { | 3856 while (!arguments.is_empty()) { |
3859 Add<HPushArgument>(arguments.RemoveLast()); | 3857 Add<HPushArgument>(arguments.RemoveLast()); |
3860 } | 3858 } |
3859 } | |
3860 | |
3861 | |
3862 template <class Instruction> | |
3863 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) { | |
3864 PushArgumentsFromEnvironment(call->argument_count()); | |
3861 return call; | 3865 return call; |
3862 } | 3866 } |
3863 | 3867 |
3864 | 3868 |
3865 void HOptimizedGraphBuilder::SetUpScope(Scope* scope) { | 3869 void HOptimizedGraphBuilder::SetUpScope(Scope* scope) { |
3866 // First special is HContext. | 3870 // First special is HContext. |
3867 HInstruction* context = Add<HContext>(); | 3871 HInstruction* context = Add<HContext>(); |
3868 environment()->BindContext(context); | 3872 environment()->BindContext(context); |
3869 | 3873 |
3870 // Create an arguments object containing the initial parameters. Set the | 3874 // Create an arguments object containing the initial parameters. Set the |
(...skipping 1619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5490 } | 5494 } |
5491 | 5495 |
5492 if (info->lookup()->IsPropertyCallbacks()) { | 5496 if (info->lookup()->IsPropertyCallbacks()) { |
5493 Push(checked_object); | 5497 Push(checked_object); |
5494 if (FLAG_inline_accessors && | 5498 if (FLAG_inline_accessors && |
5495 can_inline_accessor && | 5499 can_inline_accessor && |
5496 TryInlineGetter(info->accessor(), ast_id, return_id)) { | 5500 TryInlineGetter(info->accessor(), ast_id, return_id)) { |
5497 return NULL; | 5501 return NULL; |
5498 } | 5502 } |
5499 Add<HPushArgument>(Pop()); | 5503 Add<HPushArgument>(Pop()); |
5500 return New<HCallConstantFunction>(info->accessor(), 1); | 5504 return BuildCallConstantFunction(info->accessor(), 1, CALL_AS_METHOD); |
5501 } | 5505 } |
5502 | 5506 |
5503 ASSERT(info->lookup()->IsConstant()); | 5507 ASSERT(info->lookup()->IsConstant()); |
5504 return New<HConstant>(info->constant()); | 5508 return New<HConstant>(info->constant()); |
5505 } | 5509 } |
5506 | 5510 |
5507 | 5511 |
5508 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( | 5512 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( |
5509 BailoutId ast_id, | 5513 BailoutId ast_id, |
5510 BailoutId return_id, | 5514 BailoutId return_id, |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5775 Handle<JSObject> holder; | 5779 Handle<JSObject> holder; |
5776 if (LookupSetter(map, name, &setter, &holder)) { | 5780 if (LookupSetter(map, name, &setter, &holder)) { |
5777 AddCheckConstantFunction(holder, object, map); | 5781 AddCheckConstantFunction(holder, object, map); |
5778 if (FLAG_inline_accessors && | 5782 if (FLAG_inline_accessors && |
5779 TryInlineSetter(setter, ast_id, return_id, value)) { | 5783 TryInlineSetter(setter, ast_id, return_id, value)) { |
5780 return; | 5784 return; |
5781 } | 5785 } |
5782 Drop(2); | 5786 Drop(2); |
5783 Add<HPushArgument>(object); | 5787 Add<HPushArgument>(object); |
5784 Add<HPushArgument>(value); | 5788 Add<HPushArgument>(value); |
5785 instr = New<HCallConstantFunction>(setter, 2); | 5789 instr = BuildCallConstantFunction(setter, 2, CALL_AS_METHOD); |
5786 } else { | 5790 } else { |
5787 Drop(2); | 5791 Drop(2); |
5788 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object, | 5792 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object, |
5789 name, | 5793 name, |
5790 value, | 5794 value, |
5791 map)); | 5795 map)); |
5792 } | 5796 } |
5793 } else if (types != NULL && types->length() > 1) { | 5797 } else if (types != NULL && types->length() > 1) { |
5794 Drop(2); | 5798 Drop(2); |
5795 return HandlePolymorphicStoreNamedField(ast_id, object, value, types, name); | 5799 return HandlePolymorphicStoreNamedField(ast_id, object, value, types, name); |
(...skipping 929 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6725 HValue* receiver, | 6729 HValue* receiver, |
6726 Handle<Map> receiver_map) { | 6730 Handle<Map> receiver_map) { |
6727 // Constant functions have the nice property that the map will change if they | 6731 // Constant functions have the nice property that the map will change if they |
6728 // are overwritten. Therefore it is enough to check the map of the holder and | 6732 // are overwritten. Therefore it is enough to check the map of the holder and |
6729 // its prototypes. | 6733 // its prototypes. |
6730 AddCheckMap(receiver, receiver_map); | 6734 AddCheckMap(receiver, receiver_map); |
6731 AddCheckPrototypeMaps(holder, receiver_map); | 6735 AddCheckPrototypeMaps(holder, receiver_map); |
6732 } | 6736 } |
6733 | 6737 |
6734 | 6738 |
6739 HInstruction* HOptimizedGraphBuilder::NewPlainFunctionCall( | |
6740 HValue* fun, HValue* call_kind_value, | |
6741 int argument_count, bool pass_argument_count) { | |
6742 return New<HCallJSFunction>( | |
6743 fun, call_kind_value, argument_count, pass_argument_count); | |
6744 } | |
6745 | |
6746 | |
6747 HInstruction* HOptimizedGraphBuilder::NewArgumentAdaptorCall( | |
6748 HValue* fun, HValue* context, HValue* call_kind_value, | |
6749 int argument_count, HValue* expected_param_count) { | |
6750 CodeStubInterfaceDescriptor* descriptor = | |
6751 isolate()->call_descriptor(Isolate::ArgumentAdaptorCall); | |
6752 | |
6753 HValue* arity = Add<HConstant>(argument_count - 1); | |
6754 | |
6755 HValue *op_vals[] = { fun, context, call_kind_value, arity, | |
Toon Verwaest
2013/12/18 16:11:41
HValue*
Jarin
2013/12/30 15:15:47
Done.
| |
6756 expected_param_count }; | |
6757 | |
6758 Handle<Code> adaptor = | |
6759 isolate()->builtins()->ArgumentsAdaptorTrampoline(); | |
6760 HConstant* adaptor_value = Add<HConstant>(adaptor); | |
6761 | |
6762 return New<HCallWithDescriptor>( | |
6763 adaptor_value, argument_count, descriptor, | |
6764 Vector<HValue*>(op_vals, descriptor->environment_length())); | |
6765 } | |
6766 | |
Toon Verwaest
2013/12/18 16:11:41
Two newlines between functions
Jarin
2013/12/30 15:15:47
Done.
| |
6767 HInstruction* HOptimizedGraphBuilder::BuildCallConstantFunction( | |
6768 Handle<JSFunction> jsfun, int argument_count, CallKind call_kind) { | |
6769 HValue* target = Add<HConstant>(jsfun); | |
6770 HValue* call_kind_value = Add<HConstant>(static_cast<int>(call_kind)); | |
6771 // For constant functions, we try to avoid calling the | |
6772 // argument adaptor and instead call the function directly | |
6773 int formal_parameter_count = jsfun->shared()->formal_parameter_count(); | |
6774 bool dont_adapt_arguments = | |
6775 (formal_parameter_count == | |
6776 SharedFunctionInfo::kDontAdaptArgumentsSentinel); | |
6777 int arity = argument_count - 1; | |
6778 bool can_invoke_directly = | |
6779 dont_adapt_arguments || formal_parameter_count == arity; | |
6780 if (can_invoke_directly) { | |
6781 return NewPlainFunctionCall(target, call_kind_value, | |
6782 argument_count, dont_adapt_arguments); | |
6783 } else { | |
6784 HValue* param_count_value = Add<HConstant>(formal_parameter_count); | |
6785 HValue* context = Add<HLoadNamedField>(target, | |
6786 HObjectAccess::ForFunctionContextPointer()); | |
6787 return NewArgumentAdaptorCall(target, context, call_kind_value, | |
6788 argument_count, param_count_value); | |
6789 } | |
6790 UNREACHABLE(); | |
6791 return NULL; | |
6792 } | |
6793 | |
6794 HInstruction* HOptimizedGraphBuilder::NewCallNamed( | |
6795 Handle<String> name, int argument_count) { | |
6796 CodeStubInterfaceDescriptor* descriptor = | |
6797 isolate()->call_descriptor(Isolate::NamedCall); | |
6798 | |
6799 HValue* name_val = Add<HConstant>(name); | |
6800 HValue *op_vals[] = { context(), name_val }; | |
Toon Verwaest
2013/12/18 16:11:41
HValue*
Jarin
2013/12/30 15:15:47
Done.
| |
6801 | |
6802 int arity = argument_count - 1; | |
6803 Handle<Code> ic = | |
6804 isolate()->stub_cache()->ComputeCallInitialize(arity, | |
6805 RelocInfo::CODE_TARGET); | |
6806 HConstant* ic_value = Add<HConstant>(ic); | |
6807 | |
6808 return New<HCallWithDescriptor>( | |
6809 ic_value, argument_count, descriptor, | |
6810 Vector<HValue*>(op_vals, descriptor->environment_length())); | |
6811 } | |
6812 | |
6813 | |
6814 HInstruction* HOptimizedGraphBuilder::NewCallKeyed( | |
6815 HValue* key, int argument_count) { | |
6816 CodeStubInterfaceDescriptor* descriptor = | |
6817 isolate()->call_descriptor(Isolate::KeyedCall); | |
6818 | |
6819 HValue *op_vals[] = { context(), key }; | |
6820 | |
6821 int arity = argument_count - 1; | |
6822 Handle<Code> ic = | |
6823 isolate()->stub_cache()->ComputeKeyedCallInitialize(arity); | |
6824 HConstant* ic_value = Add<HConstant>(ic); | |
6825 | |
6826 return New<HCallWithDescriptor>( | |
6827 ic_value, argument_count, descriptor, | |
6828 Vector<HValue*>(op_vals, descriptor->environment_length())); | |
6829 } | |
6830 | |
6735 class FunctionSorter { | 6831 class FunctionSorter { |
6736 public: | 6832 public: |
6737 FunctionSorter() : index_(0), ticks_(0), ast_length_(0), src_length_(0) { } | 6833 FunctionSorter() : index_(0), ticks_(0), ast_length_(0), src_length_(0) { } |
6738 FunctionSorter(int index, int ticks, int ast_length, int src_length) | 6834 FunctionSorter(int index, int ticks, int ast_length, int src_length) |
6739 : index_(index), | 6835 : index_(index), |
6740 ticks_(ticks), | 6836 ticks_(ticks), |
6741 ast_length_(ast_length), | 6837 ast_length_(ast_length), |
6742 src_length_(src_length) { } | 6838 src_length_(src_length) { } |
6743 | 6839 |
6744 int index() const { return index_; } | 6840 int index() const { return index_; } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6780 if (FLAG_trace_inlining) { | 6876 if (FLAG_trace_inlining) { |
6781 Handle<JSFunction> caller = current_info()->closure(); | 6877 Handle<JSFunction> caller = current_info()->closure(); |
6782 SmartArrayPointer<char> caller_name = | 6878 SmartArrayPointer<char> caller_name = |
6783 caller->shared()->DebugName()->ToCString(); | 6879 caller->shared()->DebugName()->ToCString(); |
6784 PrintF("Trying to inline the polymorphic call to %s from %s\n", | 6880 PrintF("Trying to inline the polymorphic call to %s from %s\n", |
6785 name->ToCString().get(), caller_name.get()); | 6881 name->ToCString().get(), caller_name.get()); |
6786 } | 6882 } |
6787 | 6883 |
6788 if (!TryInlineCall(expr)) { | 6884 if (!TryInlineCall(expr)) { |
6789 int argument_count = expr->arguments()->length() + 1; // Includes receiver. | 6885 int argument_count = expr->arguments()->length() + 1; // Includes receiver. |
6790 HCallConstantFunction* call = | 6886 HInstruction* call = |
6791 New<HCallConstantFunction>(expr->target(), argument_count); | 6887 BuildCallConstantFunction(expr->target(), |
6792 PreProcessCall(call); | 6888 argument_count, |
6889 CALL_AS_METHOD); | |
6890 PushArgumentsFromEnvironment(argument_count); | |
6793 AddInstruction(call); | 6891 AddInstruction(call); |
6794 if (!ast_context()->IsEffect()) Push(call); | 6892 if (!ast_context()->IsEffect()) Push(call); |
6795 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); | 6893 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); |
6796 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); | 6894 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); |
6797 } | 6895 } |
6798 | 6896 |
6799 return true; | 6897 return true; |
6800 } | 6898 } |
6801 | 6899 |
6802 | 6900 |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6896 caller->shared()->DebugName()->ToCString(); | 6994 caller->shared()->DebugName()->ToCString(); |
6897 PrintF("Trying to inline the polymorphic call to %s from %s\n", | 6995 PrintF("Trying to inline the polymorphic call to %s from %s\n", |
6898 name->ToCString().get(), | 6996 name->ToCString().get(), |
6899 caller_name.get()); | 6997 caller_name.get()); |
6900 } | 6998 } |
6901 if (FLAG_polymorphic_inlining && TryInlineCall(expr)) { | 6999 if (FLAG_polymorphic_inlining && TryInlineCall(expr)) { |
6902 // Trying to inline will signal that we should bailout from the | 7000 // Trying to inline will signal that we should bailout from the |
6903 // entire compilation by setting stack overflow on the visitor. | 7001 // entire compilation by setting stack overflow on the visitor. |
6904 if (HasStackOverflow()) return; | 7002 if (HasStackOverflow()) return; |
6905 } else { | 7003 } else { |
6906 HCallConstantFunction* call = | 7004 HInstruction* call = |
6907 New<HCallConstantFunction>(expr->target(), argument_count); | 7005 BuildCallConstantFunction(expr->target(), |
6908 PreProcessCall(call); | 7006 argument_count, |
7007 CALL_AS_METHOD); | |
7008 PushArgumentsFromEnvironment(argument_count); | |
6909 AddInstruction(call); | 7009 AddInstruction(call); |
6910 if (!ast_context()->IsEffect()) Push(call); | 7010 if (!ast_context()->IsEffect()) Push(call); |
6911 } | 7011 } |
6912 | 7012 |
6913 if (current_block() != NULL) Goto(join); | 7013 if (current_block() != NULL) Goto(join); |
6914 set_current_block(if_false); | 7014 set_current_block(if_false); |
6915 } | 7015 } |
6916 | 7016 |
6917 // Finish up. Unconditionally deoptimize if we've handled all the maps we | 7017 // Finish up. Unconditionally deoptimize if we've handled all the maps we |
6918 // know about and do not want to handle ones we've never seen. Otherwise | 7018 // know about and do not want to handle ones we've never seen. Otherwise |
6919 // use a generic IC. | 7019 // use a generic IC. |
6920 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) { | 7020 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) { |
6921 // Because the deopt may be the only path in the polymorphic call, make sure | 7021 // Because the deopt may be the only path in the polymorphic call, make sure |
6922 // that the environment stack matches the depth on deopt that it otherwise | 7022 // that the environment stack matches the depth on deopt that it otherwise |
6923 // would have had after a successful call. | 7023 // would have had after a successful call. |
6924 Drop(argument_count); | 7024 Drop(argument_count); |
6925 if (!ast_context()->IsEffect()) Push(graph()->GetConstant0()); | 7025 if (!ast_context()->IsEffect()) Push(graph()->GetConstant0()); |
6926 FinishExitWithHardDeoptimization("Unknown map in polymorphic call", join); | 7026 FinishExitWithHardDeoptimization("Unknown map in polymorphic call", join); |
6927 } else { | 7027 } else { |
6928 HCallNamed* call = New<HCallNamed>(name, argument_count); | 7028 HInstruction* call = NewCallNamed(name, argument_count); |
6929 PreProcessCall(call); | 7029 PushArgumentsFromEnvironment(argument_count); |
6930 | 7030 |
6931 if (join != NULL) { | 7031 if (join != NULL) { |
6932 AddInstruction(call); | 7032 AddInstruction(call); |
6933 if (!ast_context()->IsEffect()) Push(call); | 7033 if (!ast_context()->IsEffect()) Push(call); |
6934 Goto(join); | 7034 Goto(join); |
6935 } else { | 7035 } else { |
6936 return ast_context()->ReturnInstruction(call, expr->id()); | 7036 return ast_context()->ReturnInstruction(call, expr->id()); |
6937 } | 7037 } |
6938 } | 7038 } |
6939 | 7039 |
(...skipping 697 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7637 ElementsKind kind = expr->KeyedArrayCallIsHoley() | 7737 ElementsKind kind = expr->KeyedArrayCallIsHoley() |
7638 ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS; | 7738 ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS; |
7639 | 7739 |
7640 Handle<Map> map(isolate()->get_initial_js_array_map(kind)); | 7740 Handle<Map> map(isolate()->get_initial_js_array_map(kind)); |
7641 | 7741 |
7642 HValue* function = BuildMonomorphicElementAccess( | 7742 HValue* function = BuildMonomorphicElementAccess( |
7643 receiver, key, NULL, NULL, map, false, STANDARD_STORE); | 7743 receiver, key, NULL, NULL, map, false, STANDARD_STORE); |
7644 | 7744 |
7645 call = New<HCallFunction>(function, argument_count); | 7745 call = New<HCallFunction>(function, argument_count); |
7646 } else { | 7746 } else { |
7647 call = New<HCallKeyed>(key, argument_count); | 7747 call = NewCallKeyed(key, argument_count); |
7648 } | 7748 } |
7649 Drop(argument_count + 1); // 1 is the key. | 7749 Drop(argument_count + 1); // 1 is the key. |
7650 return ast_context()->ReturnInstruction(call, expr->id()); | 7750 return ast_context()->ReturnInstruction(call, expr->id()); |
7651 } | 7751 } |
7652 | 7752 |
7653 // Named function call. | 7753 // Named function call. |
7654 if (TryCallApply(expr)) return; | 7754 if (TryCallApply(expr)) return; |
7655 | 7755 |
7656 CHECK_ALIVE(VisitForValue(prop->obj())); | 7756 CHECK_ALIVE(VisitForValue(prop->obj())); |
7657 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 7757 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
(...skipping 18 matching lines...) Expand all Loading... | |
7676 PrintF("\n"); | 7776 PrintF("\n"); |
7677 } | 7777 } |
7678 return; | 7778 return; |
7679 } | 7779 } |
7680 | 7780 |
7681 if (CallStubCompiler::HasCustomCallGenerator(expr->target()) || | 7781 if (CallStubCompiler::HasCustomCallGenerator(expr->target()) || |
7682 expr->check_type() != RECEIVER_MAP_CHECK) { | 7782 expr->check_type() != RECEIVER_MAP_CHECK) { |
7683 // When the target has a custom call IC generator, use the IC, | 7783 // When the target has a custom call IC generator, use the IC, |
7684 // because it is likely to generate better code. Also use the IC | 7784 // because it is likely to generate better code. Also use the IC |
7685 // when a primitive receiver check is required. | 7785 // when a primitive receiver check is required. |
7686 call = PreProcessCall(New<HCallNamed>(name, argument_count)); | 7786 call = NewCallNamed(name, argument_count); |
7787 PushArgumentsFromEnvironment(argument_count); | |
7687 } else { | 7788 } else { |
7688 AddCheckConstantFunction(expr->holder(), receiver, map); | 7789 AddCheckConstantFunction(expr->holder(), receiver, map); |
7689 | 7790 |
7690 if (TryInlineCall(expr)) return; | 7791 if (TryInlineCall(expr)) return; |
7691 call = PreProcessCall( | 7792 call = BuildCallConstantFunction(expr->target(), |
7692 New<HCallConstantFunction>(expr->target(), argument_count)); | 7793 argument_count, |
7794 CALL_AS_METHOD); | |
7795 PushArgumentsFromEnvironment(argument_count); | |
7693 } | 7796 } |
7694 } else if (types != NULL && types->length() > 1) { | 7797 } else if (types != NULL && types->length() > 1) { |
7695 ASSERT(expr->check_type() == RECEIVER_MAP_CHECK); | 7798 ASSERT(expr->check_type() == RECEIVER_MAP_CHECK); |
7696 HandlePolymorphicCallNamed(expr, receiver, types, name); | 7799 HandlePolymorphicCallNamed(expr, receiver, types, name); |
7697 return; | 7800 return; |
7698 | 7801 |
7699 } else { | 7802 } else { |
7700 call = PreProcessCall(New<HCallNamed>(name, argument_count)); | 7803 call = NewCallNamed(name, argument_count); |
7804 PushArgumentsFromEnvironment(argument_count); | |
7701 } | 7805 } |
7702 } else { | 7806 } else { |
7703 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 7807 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
7704 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { | 7808 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { |
7705 return Bailout(kPossibleDirectCallToEval); | 7809 return Bailout(kPossibleDirectCallToEval); |
7706 } | 7810 } |
7707 | 7811 |
7708 bool global_call = proxy != NULL && proxy->var()->IsUnallocated(); | 7812 bool global_call = proxy != NULL && proxy->var()->IsUnallocated(); |
7709 if (global_call) { | 7813 if (global_call) { |
7710 Variable* var = proxy->var(); | 7814 Variable* var = proxy->var(); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7748 } | 7852 } |
7749 if (TryInlineCall(expr)) return; | 7853 if (TryInlineCall(expr)) return; |
7750 | 7854 |
7751 if (expr->target().is_identical_to(current_info()->closure())) { | 7855 if (expr->target().is_identical_to(current_info()->closure())) { |
7752 graph()->MarkRecursive(); | 7856 graph()->MarkRecursive(); |
7753 } | 7857 } |
7754 | 7858 |
7755 if (CallStubCompiler::HasCustomCallGenerator(expr->target())) { | 7859 if (CallStubCompiler::HasCustomCallGenerator(expr->target())) { |
7756 // When the target has a custom call IC generator, use the IC, | 7860 // When the target has a custom call IC generator, use the IC, |
7757 // because it is likely to generate better code. | 7861 // because it is likely to generate better code. |
7758 call = PreProcessCall(New<HCallNamed>(var->name(), argument_count)); | 7862 call = NewCallNamed(var->name(), argument_count); |
7863 PushArgumentsFromEnvironment(argument_count); | |
7759 } else { | 7864 } else { |
7760 call = PreProcessCall(New<HCallKnownGlobal>( | 7865 call = BuildCallConstantFunction(expr->target(), |
7761 expr->target(), argument_count)); | 7866 argument_count, CALL_AS_FUNCTION); |
7867 PushArgumentsFromEnvironment(argument_count); | |
7762 } | 7868 } |
7763 } else { | 7869 } else { |
7764 HGlobalObject* receiver = Add<HGlobalObject>(); | 7870 HGlobalObject* receiver = Add<HGlobalObject>(); |
7765 Push(Add<HPushArgument>(receiver)); | 7871 Push(Add<HPushArgument>(receiver)); |
7766 CHECK_ALIVE(VisitArgumentList(expr->arguments())); | 7872 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
7767 | 7873 |
7768 call = New<HCallGlobal>(var->name(), argument_count); | 7874 call = New<HCallGlobal>(var->name(), argument_count); |
7769 Drop(argument_count); | 7875 Drop(argument_count); |
7770 } | 7876 } |
7771 | 7877 |
(...skipping 3041 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10813 if (ShouldProduceTraceOutput()) { | 10919 if (ShouldProduceTraceOutput()) { |
10814 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 10920 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
10815 } | 10921 } |
10816 | 10922 |
10817 #ifdef DEBUG | 10923 #ifdef DEBUG |
10818 graph_->Verify(false); // No full verify. | 10924 graph_->Verify(false); // No full verify. |
10819 #endif | 10925 #endif |
10820 } | 10926 } |
10821 | 10927 |
10822 } } // namespace v8::internal | 10928 } } // namespace v8::internal |
OLD | NEW |